Re: Using BigInteger as argument to AbstractJdbc2Statement.setObject - Mailing list pgsql-jdbc

From Sylvain Leroux
Subject Re: Using BigInteger as argument to AbstractJdbc2Statement.setObject
Date
Msg-id 4A798325.4030607@wanadoo.fr
Whole thread Raw
In response to Re: Using BigInteger as argument to AbstractJdbc2Statement.setObject  (Oliver Jowett <oliver@opencloud.com>)
Responses Re: Using BigInteger as argument to AbstractJdbc2Statement.setObject  (Oliver Jowett <oliver@opencloud.com>)
List pgsql-jdbc
Hi,

and first of all, thanks for your answer.

Oliver Jowett a écrit :
> Why NUMERIC instead of an integer type?
>
> Might as well make setBigInteger() private if you're not also going to
> expose it on PGStatement (I don't think it needs to be exposed there)
According to the JDK doc, java.math.BigInteger provides
"arbitrary-precision integers".
The closest match will be NUMERIC since it allows up to 1000 digits. As
far as I know, the integer types have much narrower range.

*Or* could it be required to inspect the BigInteger in order to use the
most appropriate type? But, I don't see any benefits here: it appears
not to be a problem to send a NUMERIC value for an INTEGER column - as
far as the value is in the supported range.

Concerning the visibility of setBigInteger(), you're perfectly right: it
should be private [I must admit it was a (too) quick-and-dirty patch -
mostly a copy of setBigDecimal - sorry ;) ]

>
> Incidentally, the JDBC spec does provide a standard mapping from
> BigDecimal (not BigInteger) to NUMERIC.
You are right here too: I've double checked the JDBC documentation.
There's no mention of the BigInteger type - whereas the BigDecimal type
is supported.

I could have lived with that, but Jython maps values out of the Python
integer range to BigInteger. Not BigDecimal. Which is perfectly legitimate.
Moreover, I have done some tests with Groovy. It has somewhat the same
behavior and wraps literal integers that exceed the ''long'' range in a
BigInteger. So this could be definitively a concern for using prepared
statements with scripting languages.


As an attachment is a modified version of the patch - with setBigInteger
set private.


Sylvain

--
Website: http://www.chicoree.fr
Index: org/postgresql/jdbc2/AbstractJdbc2Statement.java
===================================================================
RCS file: /cvsroot/jdbc/pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java,v
retrieving revision 1.114
diff -u -8 -p -r1.114 AbstractJdbc2Statement.java
--- org/postgresql/jdbc2/AbstractJdbc2Statement.java    27 May 2009 23:55:19 -0000    1.114
+++ org/postgresql/jdbc2/AbstractJdbc2Statement.java    5 Aug 2009 12:29:20 -0000
@@ -1224,16 +1224,36 @@ public abstract class AbstractJdbc2State
      */
     public void setDouble(int parameterIndex, double x) throws SQLException
     {
         checkClosed();
         bindLiteral(parameterIndex, Double.toString(x), Oid.FLOAT8);
     }

     /*
+     * Set a parameter to a java.lang.BigInteger value.  The driver
+     * converts this to a SQL NUMERIC value when it sends it to the
+     * database.
+     *
+     * <b>This is an extension to the JDBC API!</b>
+     *
+     * @param parameterIndex the first parameter is 1...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs
+     */
+    private void setBigInteger(int parameterIndex, BigInteger x) throws SQLException
+    {
+        checkClosed();
+        if (x == null)
+            setNull(parameterIndex, Types.DECIMAL);
+        else
+            bindLiteral(parameterIndex, x.toString(), Oid.NUMERIC);
+    }
+
+    /*
      * Set a parameter to a java.lang.BigDecimal value.  The driver
      * converts this to a SQL NUMERIC value when it sends it to the
      * database.
      *
      * @param parameterIndex the first parameter is 1...
      * @param x the parameter value
      * @exception SQLException if a database access error occurs
      */
@@ -1731,16 +1751,18 @@ public abstract class AbstractJdbc2State
     {
         checkClosed();
         if (x == null)
             setNull(parameterIndex, Types.OTHER);
         else if (x instanceof String)
             setString(parameterIndex, (String)x);
         else if (x instanceof BigDecimal)
             setBigDecimal(parameterIndex, (BigDecimal)x);
+        else if (x instanceof BigInteger)
+            setBigInteger(parameterIndex, (BigInteger)x);
         else if (x instanceof Short)
             setShort(parameterIndex, ((Short)x).shortValue());
         else if (x instanceof Integer)
             setInt(parameterIndex, ((Integer)x).intValue());
         else if (x instanceof Long)
             setLong(parameterIndex, ((Long)x).longValue());
         else if (x instanceof Float)
             setFloat(parameterIndex, ((Float)x).floatValue());

pgsql-jdbc by date:

Previous
From: Oliver Jowett
Date:
Subject: Re: Using BigInteger as argument to AbstractJdbc2Statement.setObject
Next
From: Sylvain Leroux
Date:
Subject: Re: float4 or real in function parameter -> PSQLException: ERROR function in_test4(double precision) does not exist