Subject Re: [Firebird-Java] Re: Repost: Problem reading large numbers
Author Uwe Jäger
Hi,

I recommend applying the complete patch.

java.math.BigDecimal has no constructor with an long argument, only
double; therefore you are allways in danger loosing precision when you
create a BigDecimal with new. Using the factory method "valueOf" also
may improve performance as the implementation of BigDecimal can reuse
existing objects (but I haven't really checked the implementation :-)).

So just to be on the save side, and it should break any working code ...

Kind regards
Uwe

Blas Rodriguez Somoza wrote:
> Hello
>
> Thanks for your patch.
>
> I have committed a modified version of your getBigDecimal patch. The change is smaller than yours because it appears that change
> in setBigDecimal is not necessary and we try to make minimal changes on the source to avoid introducing new errors.
>
> Please try with a fresh CVS version and let me know if the change solve your problem.
>
> Regards
> Blas Rodriguez Somoza
>
> ----- Original Message -----
> From: "Uwe Jäger" <jaeger@...>
> To: <Firebird-Java@yahoogroups.com>
> Sent: Monday, July 29, 2002 3:37 PM
> Subject: Re: [Firebird-Java] Re: Repost: Problem reading large numbers
>
>
>
>>Well,
>>
>>done it myself ... please find a patch attached; the problem was that
>>BigDecimals were created through double values, but those have only
>>about 15 significant digits, not 18 as needed in my scenario.
>>
>>Kind regards
>>Uwe
>>
>>rrokytskyy wrote:
>>
>>>Uwe,
>>>
>>>I will check this issue and will report the result/fix.
>>>
>>>Best regards,
>>>Roman Rokytskyy
>>>
>>>--- In Firebird-Java@y..., Uwe Jäger <jaeger@v...> wrote:
>>>
>>>
>>>>Hi,
>>>>
>>>>we use NUMERIC(18) to store generated id's for the data in our
>>>
>>>database.
>>>
>>>
>>>>When I execute a select with the jdbc driver, the driver returns
>>>
>>>the id
>>>
>>>
>>>>with the last digit set to 0 instead of the real value.
>>>>
>>>>You should be able to reproduce this, e.g.
>>>>
>>>>CREATE TABLE MenuTree_T (
>>>> ObjectID NUMERIC(18) NOT NULL,
>>>> ObjectTS TIMESTAMP NOT NULL,
>>>> LastUserID VARCHAR(20) NOT NULL,
>>>> TreeType NUMERIC(2) NOT NULL,
>>>> OIDUser NUMERIC(18),
>>>> CONSTRAINT MenuTree_P
>>>> PRIMARY KEY (ObjectID)
>>>>);
>>>>
>>>>INSERT into menutree_T values (
>>>> '48638933116718883',
>>>> '2002-05-10 15:05:25.0',
>>>> 'system',
>>>> 0,
>>>> NULL
>>>>);
>>>>
>>>>SELECT * FROM MENUTREE_T where treetype = 0 and oiduser is null;
>>>>
>>>>and retrieve the objectid with resultset.getBigDecimal("OBJECTID",
>>>
>>>0);
>>>
>>>
>>>>This will result in the objectid being 48638933116718880.
>>>>
>>>>I hope you can reproduce this and find the problem.
>>>>
>>>>This happens with the (latest?, 18/7/2002) version from cvs.
>>>>
>>>>Kind regards
>>>>Uwe
>>>
>>>
>>>
>>>
>>>To unsubscribe from this group, send an email to:
>>>Firebird-Java-unsubscribe@yahoogroups.com
>>>
>>>
>>>
>>>Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>>>
>>
>>
>>
>>To unsubscribe from this group, send an email to:
>>Firebird-Java-unsubscribe@yahoogroups.com
>>
>>
>>
>>Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>>
>>
>
>
>
> --------------------------------------------------------------------------------
>
>
>
>>Index: src/org/firebirdsql/jdbc/FBIntegerField.java
>>===================================================================
>>RCS file: /cvsroot/firebird/client-java/src/org/firebirdsql/jdbc/FBIntegerField.java,v
>>retrieving revision 1.5
>>diff -c -r1.5 FBIntegerField.java
>>*** src/org/firebirdsql/jdbc/FBIntegerField.java 25 May 2002 01:36:25 -0000 1.5
>>--- src/org/firebirdsql/jdbc/FBIntegerField.java 29 Jul 2002 13:13:24 -0000
>>***************
>>*** 86,95 ****
>>
>> return ((Integer)field.sqldata).doubleValue();
>> }
>>! java.math.BigDecimal getBigDecimal() throws SQLException {
>> if (isNull()) return BIGDECIMAL_NULL_VALUE;
>>
>>! return new java.math.BigDecimal(((Integer)field.sqldata).doubleValue());
>> }
>> Object getObject() throws SQLException {
>> if (isNull()) return OBJECT_NULL_VALUE;
>>--- 86,95 ----
>>
>> return ((Integer)field.sqldata).doubleValue();
>> }
>>! BigDecimal getBigDecimal() throws SQLException {
>> if (isNull()) return BIGDECIMAL_NULL_VALUE;
>>
>>! return BigDecimal.valueOf(((Integer)field.sqldata).longValue());
>> }
>> Object getObject() throws SQLException {
>> if (isNull()) return OBJECT_NULL_VALUE;
>>***************
>>*** 159,173 ****
>> void setByte(byte value) throws java.sql.SQLException {
>> setInteger((int)value);
>> }
>>! void setBigDecimal(java.math.BigDecimal value) throws SQLException {
>> if (value == null) {
>> setNull(true);
>> return;
>> }
>>
>> // check if value is within bounds
>>! if (value.compareTo(new BigDecimal(MAX_INT_VALUE)) > 0 ||
>>! value.compareTo(new BigDecimal(MIN_INT_VALUE)) < 0)
>> throw (SQLException)createException(
>> BIGDECIMAL_CONVERSION_ERROR+" "+value).fillInStackTrace();
>>
>>--- 159,173 ----
>> void setByte(byte value) throws java.sql.SQLException {
>> setInteger((int)value);
>> }
>>! void setBigDecimal(BigDecimal value) throws SQLException {
>> if (value == null) {
>> setNull(true);
>> return;
>> }
>>
>> // check if value is within bounds
>>! if (value.compareTo(BigDecimal.valueOf(MAX_INT_VALUE)) > 0 ||
>>! value.compareTo(BigDecimal.valueOf(MIN_INT_VALUE)) < 0)
>> throw (SQLException)createException(
>> BIGDECIMAL_CONVERSION_ERROR+" "+value).fillInStackTrace();
>>
>>Index: src/org/firebirdsql/jdbc/FBLongField.java
>>===================================================================
>>RCS file: /cvsroot/firebird/client-java/src/org/firebirdsql/jdbc/FBLongField.java,v
>>retrieving revision 1.5
>>diff -c -r1.5 FBLongField.java
>>*** src/org/firebirdsql/jdbc/FBLongField.java 25 May 2002 01:36:25 -0000 1.5
>>--- src/org/firebirdsql/jdbc/FBLongField.java 29 Jul 2002 13:13:24 -0000
>>***************
>>*** 93,102 ****
>>
>> return ((Long)field.sqldata).doubleValue();
>> }
>>! java.math.BigDecimal getBigDecimal() throws SQLException {
>> if (isNull()) return BIGDECIMAL_NULL_VALUE;
>>
>>! return new java.math.BigDecimal(((Long)field.sqldata).doubleValue());
>> }
>> Object getObject() throws SQLException {
>> if (isNull()) return OBJECT_NULL_VALUE;
>>--- 93,102 ----
>>
>> return ((Long)field.sqldata).doubleValue();
>> }
>>! BigDecimal getBigDecimal() throws SQLException {
>> if (isNull()) return BIGDECIMAL_NULL_VALUE;
>>
>>! return BigDecimal.valueOf(((Long)field.sqldata).longValue());
>> }
>> Object getObject() throws SQLException {
>> if (isNull()) return OBJECT_NULL_VALUE;
>>***************
>>*** 160,174 ****
>> void setByte(byte value) throws java.sql.SQLException {
>> setLong((long)value);
>> }
>>! void setBigDecimal(java.math.BigDecimal value) throws SQLException {
>> if (value == null) {
>> setNull(true);
>> return;
>> }
>>
>> // check if value is within bounds
>>! if (value.compareTo(new BigDecimal(MAX_LONG_VALUE)) > 0 ||
>>! value.compareTo(new BigDecimal(MIN_LONG_VALUE)) < 0)
>> throw (SQLException)createException(
>> BIGDECIMAL_CONVERSION_ERROR+" "+value).fillInStackTrace();
>>
>>--- 160,174 ----
>> void setByte(byte value) throws java.sql.SQLException {
>> setLong((long)value);
>> }
>>! void setBigDecimal(BigDecimal value) throws SQLException {
>> if (value == null) {
>> setNull(true);
>> return;
>> }
>>
>> // check if value is within bounds
>>! if (value.compareTo(BigDecimal.valueOf(MAX_LONG_VALUE)) > 0 ||
>>! value.compareTo(BigDecimal.valueOf(MIN_LONG_VALUE)) < 0)
>> throw (SQLException)createException(
>> BIGDECIMAL_CONVERSION_ERROR+" "+value).fillInStackTrace();
>>
>>Index: src/org/firebirdsql/jdbc/FBShortField.java
>>===================================================================
>>RCS file: /cvsroot/firebird/client-java/src/org/firebirdsql/jdbc/FBShortField.java,v
>>retrieving revision 1.5
>>diff -c -r1.5 FBShortField.java
>>*** src/org/firebirdsql/jdbc/FBShortField.java 25 May 2002 01:37:35 -0000 1.5
>>--- src/org/firebirdsql/jdbc/FBShortField.java 29 Jul 2002 13:13:24 -0000
>>***************
>>*** 82,88 ****
>> BigDecimal getBigDecimal() throws SQLException {
>> if (isNull()) return BIGDECIMAL_NULL_VALUE;
>>
>>! return new java.math.BigDecimal(((Short)field.sqldata).doubleValue());
>> }
>> Object getObject() throws SQLException {
>> if (isNull()) return OBJECT_NULL_VALUE;
>>--- 82,88 ----
>> BigDecimal getBigDecimal() throws SQLException {
>> if (isNull()) return BIGDECIMAL_NULL_VALUE;
>>
>>! return BigDecimal.valueOf(((Short)field.sqldata).longValue());
>> }
>> Object getObject() throws SQLException {
>> if (isNull()) return OBJECT_NULL_VALUE;
>>***************
>>*** 168,175 ****
>> }
>>
>> // check if value is within bounds
>>! if (value.compareTo(new BigDecimal(MAX_SHORT_VALUE)) > 0 ||
>>! value.compareTo(new BigDecimal(MIN_SHORT_VALUE)) < 0)
>> throw (SQLException)createException(
>> BIGDECIMAL_CONVERSION_ERROR+" "+value).fillInStackTrace();
>>
>>--- 168,175 ----
>> }
>>
>> // check if value is within bounds
>>! if (value.compareTo(BigDecimal.valueOf(MAX_SHORT_VALUE)) > 0 ||
>>! value.compareTo(BigDecimal.valueOf(MIN_SHORT_VALUE)) < 0)
>> throw (SQLException)createException(
>> BIGDECIMAL_CONVERSION_ERROR+" "+value).fillInStackTrace();
>>
>>
>
>
>
> To unsubscribe from this group, send an email to:
> Firebird-Java-unsubscribe@yahoogroups.com
>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>