Обсуждение: Bad BigDecimal

Поиск
Список
Период
Сортировка

Bad BigDecimal

От
"Jason Orendorff"
Дата:
Reply-To: sender

Hi.  I'm having a problem with the JDBC driver.  It's excellent for
the most part - kudos to Mr. Mount - and this is the first problem
I've run into.  I think there's a bug; read below for my explanation
and (I think) the fix.

The problem:  When I call getBigDecimal() on a ResultSet, it
sometimes throws an exception:
 Bad BigDecimal 174.50   at org.postgresql.jdbc2.ResultSet.getBigDecimal(ResultSet.java:373)   at
org.postgresql.jdbc2.ResultSet.getBigDecimal(ResultSet.java:984)  ...blah blah blah...
org.postgresql.util.PSQLException:Bad BigDecimal 174.50
 

I think the problem is on line 984 of
org/postgresql/jdbc2/ResultSet.java.  Here's the method I'm looking at
(slightly reformatted to fit in this e-mail message):
 public java.math.BigDecimal getBigDecimal(int columnIndex)     throws SQLException   {     // Now must call BigDecimal
witha scale otherwise JBuilder     // barfs     return getBigDecimal(columnIndex,0);   }
 

Notice that it's calling getBigDecimal(int, int) with a 0 for the
second argument.  Here's the source of that method (again, slightly
reformatted):
 public BigDecimal getBigDecimal(int columnIndex, int scale)     throws SQLException   {     String s =
getFixedString(columnIndex);    BigDecimal val;
 
     if (s != null)       {
         try           {             val = new BigDecimal(s);           } catch (NumberFormatException e) {
thrownew PSQLException("postgresql.res.badbigdec",s);           }         if (scale==-1) return val;         try
  {             return val.setScale(scale);           } catch (ArithmeticException e) {             throw new
PSQLException("postgresql.res.badbigdec",s);          }       }     return null;              // SQL NULL   }
 

Okay.  The fact that the default scale is 0 causes essentially
the following to happen: BigDecimal val; val = new BigDecimal("174.50"); return val.setScale(0);

This causes an exception because 174.50 can't be exactly represented
by a BigDecimal that has scale 0.

The fix:  change the appropriate line to read: return getBigDecimal(columnIndex, -1);

I'm sure I'm probably overlooking something; please let me know...
Also, please copy me on replies!  Thanks!

-- 
Thanks in advance,
Jason Orendorff
freelance programmer



Re: Bad BigDecimal

От
Barry Lind
Дата:
Yes this does appear to be a bug.  Can you submit a patch to
pgsql-patches@postgresql.org with the fix.  If you don't have time, let
me know and I will submit the patch.

thanks,
--Barry



Jason Orendorff wrote:
> Reply-To: sender
>
> Hi.  I'm having a problem with the JDBC driver.  It's excellent for
> the most part - kudos to Mr. Mount - and this is the first problem
> I've run into.  I think there's a bug; read below for my explanation
> and (I think) the fix.
>
> The problem:  When I call getBigDecimal() on a ResultSet, it
> sometimes throws an exception:
>
>   Bad BigDecimal 174.50
>     at org.postgresql.jdbc2.ResultSet.getBigDecimal(ResultSet.java:373)
>     at org.postgresql.jdbc2.ResultSet.getBigDecimal(ResultSet.java:984)
>     ...blah blah blah...
>   org.postgresql.util.PSQLException: Bad BigDecimal 174.50
>
> I think the problem is on line 984 of
> org/postgresql/jdbc2/ResultSet.java.  Here's the method I'm looking at
> (slightly reformatted to fit in this e-mail message):
>
>   public java.math.BigDecimal getBigDecimal(int columnIndex)
>       throws SQLException
>     {
>       // Now must call BigDecimal with a scale otherwise JBuilder
>       // barfs
>       return getBigDecimal(columnIndex,0);
>     }
>
> Notice that it's calling getBigDecimal(int, int) with a 0 for the
> second argument.  Here's the source of that method (again, slightly
> reformatted):
>
>   public BigDecimal getBigDecimal(int columnIndex, int scale)
>       throws SQLException
>     {
>       String s = getFixedString(columnIndex);
>       BigDecimal val;
>
>       if (s != null)
>         {
>
>           try
>             {
>               val = new BigDecimal(s);
>             } catch (NumberFormatException e) {
>               throw new PSQLException("postgresql.res.badbigdec",s);
>             }
>           if (scale==-1) return val;
>           try
>             {
>               return val.setScale(scale);
>             } catch (ArithmeticException e) {
>               throw new PSQLException("postgresql.res.badbigdec",s);
>             }
>         }
>       return null;              // SQL NULL
>     }
>
> Okay.  The fact that the default scale is 0 causes essentially
> the following to happen:
>   BigDecimal val;
>   val = new BigDecimal("174.50");
>   return val.setScale(0);
>
> This causes an exception because 174.50 can't be exactly represented
> by a BigDecimal that has scale 0.
>
> The fix:  change the appropriate line to read:
>   return getBigDecimal(columnIndex, -1);
>
> I'm sure I'm probably overlooking something; please let me know...
> Also, please copy me on replies!  Thanks!
>
>