Re: BUG #12053: Strange behavior for numeric types with unspecified precision-scale - Mailing list pgsql-bugs

From Tom Lane
Subject Re: BUG #12053: Strange behavior for numeric types with unspecified precision-scale
Date
Msg-id 20726.1417220254@sss.pgh.pa.us
Whole thread Raw
In response to Re: BUG #12053: Strange behavior for numeric types with unspecified precision-scale  (Tommaso Sala <tommaso.sala@cla-it.eu>)
Responses Re: BUG #12053: Strange behavior for numeric types with unspecified precision-scale  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs
Tommaso Sala <tommaso.sala@cla-it.eu> writes:
> Hi, I already tried to log all, but it seems not to help a lot.
> In the StackOverflow question I originally linked in this bug report, I
> wrote the following:

>>>>> log_statement = 'all' gives a weirdER result:
>>>>>
>>>>> UPDATE "TABLE" SET ... "WEIRD_FIELD"=$8 ... WHERE ...
>>>>>
>>>>> DETAIL:  parameters: $1 = '7', $2 = '7', $3 = '18', $4 = '18', $5 = 'V03', $6 = 'Hz',
>>>>> $7 = 'Hz', $8 = '0.00', $9 = '0', $10 = '2', $11 = '0'

> The parameter for the weird field is printed as zero (0.00), but
> clearly it is not...

Ah, so you did have a parameterized statement and not just a plain-text
SQL command.  The log entry doesn't say whether the parameter value was
sent as text or binary, but if it had been sent as text, that would have
been exactly the string sent, and surely it'd have been read as plain old
zero.  If it had been sent as binary, this printout would be obtained the
same way as a regular "select *" would do, and we already know the bogus
value prints as 0.00 that way.

I did some experimentation and verified that if I manufacture a numeric
value that's really 0.001 but has dscale = 2, it will act precisely as
described in this report.  The commentary in numeric.c saith

 * dscale, or display scale, is the nominal precision expressed as number
 * of digits after the decimal point (it must always be >= 0 at present).
 * dscale may be more than the number of physically stored fractional digits,
 * implying that we have suppressed storage of significant trailing zeroes.
 * It should never be less than the number of stored digits, since that would
 * imply hiding digits that are present.

and that "hiding" is exactly what we're looking at.

So the question is whether it's worth adding logic to numeric_recv
to guard against bogus dscale values.  I think that detecting this
case would probably add a noticeable number of cycles to numeric_in.
(We can't just count the number of digits received, since (a) trailing
zeroes past dscale are OK, and (b) what we have at this point is
base-10000 digits not base-10 digits...)  I guess we're usually willing
to expend cycles to guard against client error, so maybe we should
do it here too.

            regards, tom lane

pgsql-bugs by date:

Previous
From: David G Johnston
Date:
Subject: Re: PQfinish() in a C multi-threaded application
Next
From: Tom Lane
Date:
Subject: Re: BUG #12053: Strange behavior for numeric types with unspecified precision-scale