Thread: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
DocSea - Patrice Delorme
Date:
Hi,

It is impossible to fetch data when numeric value in database is NaN
It throws FAST_NUMBER_FAILED
(postgresql-jdbc-9.1-902:AbstractJdbc2ResultSet:2176) because my value
is not numeric (NaN).
This is incorect behaviour since 'NaN' is a legal value in postgres for
numeric type.

problem is in postgresql-jdbc-9.1-902.jdbc4
but it seems arround for ages... since I discovered it first in
postgresql-8.3-603.jdbc3...

best regards,

P.



Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
"Kevin Grittner"
Date:
DocSea - Patrice Delorme <pdelorme@docsea.com> wrote:

> It is impossible to fetch data when numeric value in database is
> NaN
> It throws FAST_NUMBER_FAILED
> (postgresql-jdbc-9.1-902:AbstractJdbc2ResultSet:2176) because my
> value is not numeric (NaN).
> This is incorect behaviour since 'NaN' is a legal value in
> postgres for numeric type.

How do you expect what you read to be represented in Java?

-Kevin


Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
Mikko Tiihonen
Date:
On 09/11/2012 01:37 PM, DocSea - Patrice Delorme wrote:
> Hi,
>
> It is impossible to fetch data when numeric value in database is NaN
> It throws FAST_NUMBER_FAILED (postgresql-jdbc-9.1-902:AbstractJdbc2ResultSet:2176) because my value is not numeric
(NaN).
> This is incorect behaviour since 'NaN' is a legal value in postgres for numeric type.
>
> problem is in postgresql-jdbc-9.1-902.jdbc4
> but it seems areound for ages... since I discovered it first in postgresql-8.3-603.jdbc3...

Can you provide a more concrete example code to show when the FAST_NUMBER_FAILED exception is seen by jdbc using
application.

I did a quick look at the code and the exception in question looks like just a jdbc driver internal way to switch to
slowerparsing of input values when fast  
parsing fails. It should never escape to applications.

-Mikko



Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
Florent Guillaume
Date:
On Tue, Sep 11, 2012 at 4:10 PM, Kevin Grittner
<Kevin.Grittner@wicourts.gov> wrote:
> DocSea - Patrice Delorme <pdelorme@docsea.com> wrote:
>
>> It is impossible to fetch data when numeric value in database is
>> NaN
>> It throws FAST_NUMBER_FAILED
>> (postgresql-jdbc-9.1-902:AbstractJdbc2ResultSet:2176) because my
>> value is not numeric (NaN).
>> This is incorect behaviour since 'NaN' is a legal value in
>> postgres for numeric type.
>
> How do you expect what you read to be represented in Java?

java.lang.Double.NaN I guess.


--
Florent Guillaume, Director of R&D, Nuxeo
Open Source, Java EE based, Enterprise Content Management (ECM)
http://www.nuxeo.com   http://www.nuxeo.org   +33 1 40 33 79 87


Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
"David Johnston"
Date:
> -----Original Message-----
> From: pgsql-jdbc-owner@postgresql.org [mailto:pgsql-jdbc-
> owner@postgresql.org] On Behalf Of Florent Guillaume
> Sent: Wednesday, September 12, 2012 9:36 AM
> To: Kevin Grittner
> Cc: DocSea - Patrice Delorme; pgsql-jdbc@postgresql.org
> Subject: Re: [JDBC] Bug : FAST_NUMBER_FAILED when getting NaN on
> BigDecimal
>
> On Tue, Sep 11, 2012 at 4:10 PM, Kevin Grittner
> <Kevin.Grittner@wicourts.gov> wrote:
> > DocSea - Patrice Delorme <pdelorme@docsea.com> wrote:
> >
> >> It is impossible to fetch data when numeric value in database is NaN
> >> It throws FAST_NUMBER_FAILED
> >> (postgresql-jdbc-9.1-902:AbstractJdbc2ResultSet:2176) because my
> >> value is not numeric (NaN).
> >> This is incorect behaviour since 'NaN' is a legal value in postgres
> >> for numeric type.
> >
> > How do you expect what you read to be represented in Java?
>
> java.lang.Double.NaN I guess.
>
>

I would think returning a special "Double" value when the expected datatype is "BigDecimal" would cause problems.  I
wouldexpect it to return NULL since that is the closest you are going to get to the semantic meaning of NaN with the
existingBigDecimal class. 

Maybe someone would a add a class to the JDBC driver that is a sub-class of BigDecimal with infinity and NaN
query/representationfeatures but since BigDecimal does not have them, and for backwards compatibility
number-to-BigDecimalhas to remain, there really isn't any better option. 

Well, there is one.  If the driver returns NULL is these situations it could still maintain internally whether the NULL
isthe result of a conversion of INF/-INF/NaN or whether the NULL was in the data itself.  The driver could expose a
"isNaN(),isPosInf(), and isNegInf() methods that the user could query upon seeing a NULL BigDecimal so that it knows
the"meaning" of the NULL.  Backward compatibility only requires that the BigDecimal is still returned, new features can
beadded. 

You either need to cast to a "float" in PostgreSQL so that the result is stored into a "Double" in Java or figure out
someother application specific workaround. 

David J.






Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
DocSea - Patrice Delorme
Date:
Le 11/09/2012 16:10, Kevin Grittner a écrit :
> DocSea - Patrice Delorme <pdelorme@docsea.com> wrote:
>
>> It is impossible to fetch data when numeric value in database is
>> NaN
>> It throws FAST_NUMBER_FAILED
>> (postgresql-jdbc-9.1-902:AbstractJdbc2ResultSet:2176) because my
>> value is not numeric (NaN).
>> This is incorect behaviour since 'NaN' is a legal value in
>> postgres for numeric type.
>
> How do you expect what you read to be represented in Java?
>
> -Kevin
>
>
Hi Kevin,

You are right, as a matter of Fact BigDecimal does not support NaN like
Double, Float does.
However, postgres DOES support it and I find it disturbing that the
driver fails so badly without explaination (I had to dig in the driver
source to find out what the problem was).
The problem is that somehow I managed to write my Double NaN to database
but wasn't able to read it back even though I was using the very same
driver in both cases!
To me, behaviour is not coherent. Either wriiting of NaN is prevented or
reading is functional !

Maybe a more explicit Exception like "numeric NaN values not supported"
and not "org.postgresql.util.PSQLException: Bad value for type
BigDecimal : NaN;" which is rather obscure
or to Extend BigDecimal with PgBigDecimal that supports NaN (and
infinity)...

Best Regards,

P.



Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
"Albe Laurenz"
Date:
David Johnston wrote:
>>>> It is impossible to fetch data when numeric value in database is NaN

>>> How do you expect what you read to be represented in Java?

>> java.lang.Double.NaN I guess.

> If the driver returns NULL is these situations it could still maintain internally
> whether the NULL is the result of a conversion of INF/-INF/NaN or whether the NULL was in the data
> itself.  The driver could expose a "isNaN(), isPosInf(), and isNegInf() methods that the user could
> query upon seeing a NULL BigDecimal so that it knows the "meaning" of the NULL.  Backward
> compatibility only requires that the BigDecimal is still returned, new features can be added.

I don't think that's a good idea.

Apart from the fact that a null pointer isn't a good representation
for an out-of-bounds value, that would change the behaviour and might
break applications that expect the current behaviour.

I think it is OK to throw an exception if a value cannot be represented,
but it should be a meaningful message.

Yours,
Laurenz Albe

Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
"David Johnston"
Date:
>
> You are right, as a matter of Fact BigDecimal does not support NaN like
> Double, Float does.
> However, postgres DOES support it and I find it disturbing that the driver
fails
> so badly without explaination (I had to dig in the driver source to find
out
> what the problem was).
> The problem is that somehow I managed to write my Double NaN to
> database but wasn't able to read it back even though I was using the very
> same driver in both cases!
> To me, behaviour is not coherent. Either wriiting of NaN is prevented or
> reading is functional !
>
> Maybe a more explicit Exception like "numeric NaN values not supported"
> and not "org.postgresql.util.PSQLException: Bad value for type BigDecimal
:
> NaN;" which is rather obscure or to Extend BigDecimal with PgBigDecimal
that
> supports NaN (and infinity)...
>

While I can understand the frustration the behavior is such because in the
vast majority of cases storing a double into a Postgres numeric is a
reasonable thing to do (and, from the driver's standpoint, maybe impossible
to detect with certainty anyway).  The driver assuming the user of
BigDecimal knows it cannot handle NaN is also not a bad assumption to make.
Wording could maybe be improved but it susiscently reports the problem
encountered (the database sent NaN and the BigDecimal had no idea what to do
with it.  It isn't like the driver has to know that NaN means Not-A-Number.
If the database sent along 'Pig' the same error would be generated but with
'Pig' instead of NaN.

Implicit conversions can and do cause problems.  That is what happened here.
As a user you should not have tried storing a Java Double into a Postgres
numeric but you should have converted it into a BigDecimal yourself.  If you
want consistent behavior that is exactly what you would have been forced to
do anyway.  Of course you or the driver could write a wrapper do that and
also check and report meaningful exceptions when the data and the target
type do not match - but given the open source nature of the driver and the
uncommon situation you presented, it is understandable that the behavior you
saw manifested itself.  No one else with the problem felt it was important
enough to fix.

David J.




Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
"David Johnston"
Date:
> -----Original Message-----
> From: Albe Laurenz [mailto:laurenz.albe@wien.gv.at]
> Sent: Wednesday, September 12, 2012 10:48 AM
> To: David Johnston *EXTERN*; Florent Guillaume; Kevin Grittner
> Cc: DocSea - Patrice Delorme; pgsql-jdbc@postgresql.org
> Subject: RE: [JDBC] Bug : FAST_NUMBER_FAILED when getting NaN on
> BigDecimal
>
> David Johnston wrote:
> >>>> It is impossible to fetch data when numeric value in database is
> >>>> NaN
>
> >>> How do you expect what you read to be represented in Java?
>
> >> java.lang.Double.NaN I guess.
>
> > If the driver returns NULL is these situations it could still maintain
> > internally whether the NULL is the result of a conversion of
> > INF/-INF/NaN or whether the NULL was in the data itself.  The driver
> > could expose a "isNaN(), isPosInf(), and isNegInf() methods that the
> > user could query upon seeing a NULL BigDecimal so that it knows the
> "meaning" of the NULL.  Backward compatibility only requires that the
> BigDecimal is still returned, new features can be added.
>
> I don't think that's a good idea.
>
> Apart from the fact that a null pointer isn't a good representation for an out-
> of-bounds value, that would change the behaviour and might break
> applications that expect the current behaviour.
>
> I think it is OK to throw an exception if a value cannot be represented, but it
> should be a meaningful message.
>

OK.  So the API would be more along the lines of: "if you are concerned with NaN/Infinity values you can poll the
resultfirst to see if the returned value is valid or not.  If the returned value is invalid and the user tries to read
thevalue they get their exception.  If the user sees that the value is invalid (from the polling) then they should
foregoreading the value and instead interpret whatever invalid value is indicated.  An actual NULL would be a valid
value."

I am unsure exactly WHEN the exception in this case is thrown but if too early then sub-classing BigDecimal is not
possiblesince the exception would preclude the object ever being created (for backwards compatibility). 

Personally, I believe there needs to be some way to access this aspect of the PostgreSQL numeric type but it is not
somethingthat, aside from a desire for completeness, currently affects me.  Even a more fine-grained exception
hierarchy(NaNException, PositiveInfinityException, NegativeInfinityException) that the user could catch on could be
helpful(instead of having to perform string manipulation of the error message).  In any cases a non-standard class
wouldbe necessary so whether the driver provides ones or it simply provide information and requires the user to code
whateverClass is appropriate is an explicit decision to make. 

David J.






Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
Luis Flores
Date:
Hello,

All solutions seem to have a really negative side.

My opinion is:
Maintain default old behaviour (avoid break things ...)

Create url property to enable new behavior (big_decimal_nan=true)

Create new PgBigDecimal class extending BigDecimal, with constants for
NaN, NEGATIVE_INFINITY and POSITIVE_INFINITY (these values can be
created with new BigDecimal( BigInteger.valueOf( 0 ), 100 ), new
BigDecimal( BigInteger.valueOf( 0 ), 101 ), new BigDecimal(
BigInteger.valueOf( 0 ), 102 ) )

Override most BigDecimal's method to throw Exception or give correct
results on operations with these constants and converting values
from/to Double.

For those worried about using 0^X for these constants, this operation
new BigDecimal( BigInteger.valueOf( 0 ), 100 ).equals( new BigDecimal(
0 ) ) returns false, which is a good thing :)

I believe this is the only correct manner to use NaN with Numeric value.

It's easy for the programmer.

Doesn't get confused with NULL values.

Doesn't broke software.


Luis Flores

On Wed, Sep 12, 2012 at 4:02 PM, David Johnston <polobo@yahoo.com> wrote:
>> -----Original Message-----
>> From: Albe Laurenz [mailto:laurenz.albe@wien.gv.at]
>> Sent: Wednesday, September 12, 2012 10:48 AM
>> To: David Johnston *EXTERN*; Florent Guillaume; Kevin Grittner
>> Cc: DocSea - Patrice Delorme; pgsql-jdbc@postgresql.org
>> Subject: RE: [JDBC] Bug : FAST_NUMBER_FAILED when getting NaN on
>> BigDecimal
>>
>> David Johnston wrote:
>> >>>> It is impossible to fetch data when numeric value in database is
>> >>>> NaN
>>
>> >>> How do you expect what you read to be represented in Java?
>>
>> >> java.lang.Double.NaN I guess.
>>
>> > If the driver returns NULL is these situations it could still maintain
>> > internally whether the NULL is the result of a conversion of
>> > INF/-INF/NaN or whether the NULL was in the data itself.  The driver
>> > could expose a "isNaN(), isPosInf(), and isNegInf() methods that the
>> > user could query upon seeing a NULL BigDecimal so that it knows the
>> "meaning" of the NULL.  Backward compatibility only requires that the
>> BigDecimal is still returned, new features can be added.
>>
>> I don't think that's a good idea.
>>
>> Apart from the fact that a null pointer isn't a good representation for an out-
>> of-bounds value, that would change the behaviour and might break
>> applications that expect the current behaviour.
>>
>> I think it is OK to throw an exception if a value cannot be represented, but it
>> should be a meaningful message.
>>
>
> OK.  So the API would be more along the lines of: "if you are concerned with NaN/Infinity values you can poll the
resultfirst to see if the returned value is valid or not.  If the returned value is invalid and the user tries to read
thevalue they get their exception.  If the user sees that the value is invalid (from the polling) then they should
foregoreading the value and instead interpret whatever invalid value is indicated.  An actual NULL would be a valid
value."
>
> I am unsure exactly WHEN the exception in this case is thrown but if too early then sub-classing BigDecimal is not
possiblesince the exception would preclude the object ever being created (for backwards compatibility). 
>
> Personally, I believe there needs to be some way to access this aspect of the PostgreSQL numeric type but it is not
somethingthat, aside from a desire for completeness, currently affects me.  Even a more fine-grained exception
hierarchy(NaNException, PositiveInfinityException, NegativeInfinityException) that the user could catch on could be
helpful(instead of having to perform string manipulation of the error message).  In any cases a non-standard class
wouldbe necessary so whether the driver provides ones or it simply provide information and requires the user to code
whateverClass is appropriate is an explicit decision to make. 
>
> David J.
>
>
>
>
>
>
> --
> Sent via pgsql-jdbc mailing list (pgsql-jdbc@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-jdbc


Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
Dave Cramer
Date:
Patrice,

Can you provide a test case which exhibits this behaviour. Preferably
one which inserts the invalid data and can't read it back.

Dave Cramer

dave.cramer(at)credativ(dot)ca
http://www.credativ.ca


On Wed, Sep 12, 2012 at 5:00 AM, DocSea - Patrice Delorme
<pdelorme@docsea.com> wrote:
> Le 11/09/2012 16:10, Kevin Grittner a écrit :
>
>> DocSea - Patrice Delorme <pdelorme@docsea.com> wrote:
>>
>>>
>>> It is impossible to fetch data when numeric value in database is
>>> NaN
>>> It throws FAST_NUMBER_FAILED
>>> (postgresql-jdbc-9.1-902:AbstractJdbc2ResultSet:2176) because my
>>> value is not numeric (NaN).
>>> This is incorect behaviour since 'NaN' is a legal value in
>>> postgres for numeric type.
>>
>>   How do you expect what you read to be represented in Java?
>>   -Kevin
>>
>>
> Hi Kevin,
>
> You are right, as a matter of Fact BigDecimal does not support NaN like
> Double, Float does.
> However, postgres DOES support it and I find it disturbing that the driver
> fails so badly without explaination (I had to dig in the driver source to
> find out what the problem was).
> The problem is that somehow I managed to write my Double NaN to database but
> wasn't able to read it back even though I was using the very same driver in
> both cases!
> To me, behaviour is not coherent. Either wriiting of NaN is prevented or
> reading is functional !
>
> Maybe a more explicit Exception like "numeric NaN values not supported" and
> not "org.postgresql.util.PSQLException: Bad value for type BigDecimal :
> NaN;" which is rather obscure
> or to Extend BigDecimal with PgBigDecimal that supports NaN (and
> infinity)...
>
> Best Regards,
>
> P.
>
>
>
>
> --
> Sent via pgsql-jdbc mailing list (pgsql-jdbc@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-jdbc


Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
Craig Ringer
Date:
On 09/12/2012 05:00 PM, DocSea - Patrice Delorme wrote:

> You are right, as a matter of Fact BigDecimal does not support NaN like
> Double, Float does.

Yep. There are some other areas where Java and PostgreSQL don't see eye
to eye that result in even more disturbing results. My "favourite" is
infinite dates, which PostgreSQL supports but Java does not. They're
currently just truncated to Java's biggest date. This means that
round-trips through Java can mangle data in new and exciting ways.
Particularly fun with ORMs that like to list every column, changed or
not, when doing an `UPDATE`.

> However, postgres DOES support it and I find it disturbing that the
> driver fails so badly without explaination (I had to dig in the driver
> source to find out what the problem was).

Yeah, that's an issue. How would you expect it to be handled?
Preferences/advice?

> The problem is that somehow I managed to write my Double NaN to database
> but wasn't able to read it back even though I was using the very same
> driver in both cases!

Yeah, that's not good. I'm honestly not sure what to do about it,
though. PgJDBC certainly can't return a Double NaN where it'd normally
return BigDecimal.

> To me, behaviour is not coherent. Either wriiting of NaN is prevented or
> reading is functional !

Agreed, that's nasty. The thing is that NaN *is* supported for Double,
so if your column type is float8 it'll all work fine.

To prevent Double (NaN) being sent as a value for a numeric column,
PgJDBC would need to ask the server for the column type and reject the
value only if the target column were numeric. Even then I'm not sure
that'd really do the job, as it'd be trivial to accidentally or
intentionally get around with functions/casts that take a double
argument and produce numeric.

> Maybe a more explicit Exception like "numeric NaN values not supported"
> and not "org.postgresql.util.PSQLException: Bad value for type
> BigDecimal : NaN;" which is rather obscure

Certainly some improvement to the message is warranted. I'm not sure I
like the proposed one though. Maybe "BigDecimal cannot represent NaN, so
the NUMERIC 'NaN' from PostgreSQL could not be returned." ?

> or to Extend BigDecimal with PgBigDecimal that supports NaN (and
> infinity)...

Tempting, but that way may lie madness given the assumptions code tends
to make about BigDecimal. I'd be pretty reluctant to do that, though it
might prove to be the best answer.

--
Craig Ringer



Re: Bug : FAST_NUMBER_FAILED when getting NaN on BigDecimal

From
"Kevin Grittner"
Date:
Craig Ringer <ringerc@ringerc.id.au> wrote:
> On 09/12/2012 05:00 PM, DocSea - Patrice Delorme wrote:

>> Maybe a more explicit Exception like "numeric NaN values not
>> supported" and not "org.postgresql.util.PSQLException: Bad value
>> for type BigDecimal : NaN;" which is rather obscure
>
> Certainly some improvement to the message is warranted. I'm not
> sure I like the proposed one though. Maybe "BigDecimal cannot
> represent NaN, so the NUMERIC 'NaN' from PostgreSQL could not be
> returned." ?

For comparison, you can invoke the BigDecimal(double) constructor
with Double.NaN without any compile error, and at run time you get
this:

    java.lang.NumberFormatException: Infinite or NaN

How differently do we want to treat this than the all-Java parallel
situation?

-Kevin