[libpostgresql-jdbc-java] 10/11: Fix a couple of bugs in CallableStatement outputs. An oversight in the checking of actual results vs. what the caller specified for registerOutParameter was checking all register parameters against the first out parameter, not the parameter it actually corresponded with.
Emmanuel Bourg
ebourg-guest at moszumanska.debian.org
Mon Jan 9 10:19:53 UTC 2017
This is an automated email from the git hooks/post-receive script.
ebourg-guest pushed a commit to tag REL8_1_406
in repository libpostgresql-jdbc-java.
commit 75d2560f6c7212b73c49754db2d1c19f4c94e6bf
Author: Kris Jurka <books at ejurka.com>
Date: Mon May 22 09:56:34 2006 +0000
Fix a couple of bugs in CallableStatement outputs. An oversight in
the checking of actual results vs. what the caller specified for
registerOutParameter was checking all register parameters against the
first out parameter, not the parameter it actually corresponded with.
Also with a function that has an in parameter and an out parameter,
the out parameter will be registered at position 2, but will be
returned in a result at position 1 because the first input parameter
generates no output. The driver needs to correctly map between these
two parameter offsets.
Reported by Luis Londono. Fix by Dave Cramer.
---
org/postgresql/core/ParameterList.java | 13 +-
org/postgresql/core/v2/FastpathParameterList.java | 6 +-
org/postgresql/core/v2/SimpleParameterList.java | 6 +-
org/postgresql/core/v3/CompositeParameterList.java | 6 +-
org/postgresql/core/v3/SimpleParameterList.java | 15 ++-
org/postgresql/jdbc2/AbstractJdbc2Statement.java | 43 +++++--
.../test/jdbc3/Jdbc3CallableStatementTest.java | 143 +++++++++++++++++----
7 files changed, 186 insertions(+), 46 deletions(-)
diff --git a/org/postgresql/core/ParameterList.java b/org/postgresql/core/ParameterList.java
index d8a2349..50de084 100644
--- a/org/postgresql/core/ParameterList.java
+++ b/org/postgresql/core/ParameterList.java
@@ -4,7 +4,7 @@
* Copyright (c) 2004, Open Cloud Limited.
*
* IDENTIFICATION
-* $PostgreSQL: pgjdbc/org/postgresql/core/ParameterList.java,v 1.7 2005/07/04 18:50:28 davec Exp $
+* $PostgreSQL: pgjdbc/org/postgresql/core/ParameterList.java,v 1.8 2005/07/08 17:38:28 davec Exp $
*
*-------------------------------------------------------------------------
*/
@@ -40,13 +40,18 @@ public interface ParameterList {
int getParameterCount();
/**
- * Get the number of parameters in this list. This value may be different,
- * and might be zero.
+ * Get the number of IN parameters in this list.
*
- * @return the number of in parameters in this list
+ * @return the number of IN parameters in this list
*/
int getInParameterCount();
+ /**
+ * Get the number of OUT parameters in this list.
+ *
+ * @return the number of OUT parameters in this list
+ */
+ int getOutParameterCount();
/**
* Return the oids of the parameters in this list. May be null for
diff --git a/org/postgresql/core/v2/FastpathParameterList.java b/org/postgresql/core/v2/FastpathParameterList.java
index 9e2d242..0b5e518 100644
--- a/org/postgresql/core/v2/FastpathParameterList.java
+++ b/org/postgresql/core/v2/FastpathParameterList.java
@@ -4,7 +4,7 @@
* Copyright (c) 2004, Open Cloud Limited.
*
* IDENTIFICATION
-* $PostgreSQL: pgjdbc/org/postgresql/core/v2/FastpathParameterList.java,v 1.7 2005/02/01 07:27:54 jurka Exp $
+* $PostgreSQL: pgjdbc/org/postgresql/core/v2/FastpathParameterList.java,v 1.8 2005/07/04 18:50:28 davec Exp $
*
*-------------------------------------------------------------------------
*/
@@ -40,6 +40,10 @@ class FastpathParameterList implements ParameterList {
public int getInParameterCount() {
return paramValues.length;
}
+ public int getOutParameterCount()
+ {
+ return 0;
+ }
public int getParameterCount()
{
return paramValues.length;
diff --git a/org/postgresql/core/v2/SimpleParameterList.java b/org/postgresql/core/v2/SimpleParameterList.java
index da78445..902ecad 100644
--- a/org/postgresql/core/v2/SimpleParameterList.java
+++ b/org/postgresql/core/v2/SimpleParameterList.java
@@ -4,7 +4,7 @@
* Copyright (c) 2004, Open Cloud Limited.
*
* IDENTIFICATION
-* $PostgreSQL: pgjdbc/org/postgresql/core/v2/SimpleParameterList.java,v 1.6 2005/02/01 07:27:54 jurka Exp $
+* $PostgreSQL: pgjdbc/org/postgresql/core/v2/SimpleParameterList.java,v 1.7 2005/07/04 18:50:28 davec Exp $
*
*-------------------------------------------------------------------------
*/
@@ -41,6 +41,10 @@ class SimpleParameterList implements ParameterList {
{
return paramValues.length;
}
+ public int getOutParameterCount()
+ {
+ return 1;
+ }
public int[] getTypeOIDs() {
return null;
}
diff --git a/org/postgresql/core/v3/CompositeParameterList.java b/org/postgresql/core/v3/CompositeParameterList.java
index 23892e2..ec5d9a3 100644
--- a/org/postgresql/core/v3/CompositeParameterList.java
+++ b/org/postgresql/core/v3/CompositeParameterList.java
@@ -4,7 +4,7 @@
* Copyright (c) 2004, Open Cloud Limited.
*
* IDENTIFICATION
-* $PostgreSQL: pgjdbc/org/postgresql/core/v3/CompositeParameterList.java,v 1.7 2005/02/01 07:27:54 jurka Exp $
+* $PostgreSQL: pgjdbc/org/postgresql/core/v3/CompositeParameterList.java,v 1.8 2005/07/04 18:50:29 davec Exp $
*
*-------------------------------------------------------------------------
*/
@@ -55,6 +55,10 @@ class CompositeParameterList implements V3ParameterList {
public int getInParameterCount() {
return total;
}
+ public int getOutParameterCount()
+ {
+ return 0;
+ }
public int[] getTypeOIDs() {
int oids[] = new int[total];
diff --git a/org/postgresql/core/v3/SimpleParameterList.java b/org/postgresql/core/v3/SimpleParameterList.java
index ad3f295..39168ea 100644
--- a/org/postgresql/core/v3/SimpleParameterList.java
+++ b/org/postgresql/core/v3/SimpleParameterList.java
@@ -4,7 +4,7 @@
* Copyright (c) 2004, Open Cloud Limited.
*
* IDENTIFICATION
-* $PostgreSQL: pgjdbc/org/postgresql/core/v3/SimpleParameterList.java,v 1.9 2005/07/04 18:50:29 davec Exp $
+* $PostgreSQL: pgjdbc/org/postgresql/core/v3/SimpleParameterList.java,v 1.10 2005/07/08 17:38:29 davec Exp $
*
*-------------------------------------------------------------------------
*/
@@ -75,6 +75,19 @@ class SimpleParameterList implements V3ParameterList {
{
return paramValues.length;
}
+ public int getOutParameterCount()
+ {
+ int count=0;
+ for( int i=paramTypes.length; --i >= 0;)
+ {
+ if ((direction[i] & OUT) == OUT )
+ {
+ count++;
+ }
+ }
+ return count;
+
+ }
public int getInParameterCount()
{
int count=0;
diff --git a/org/postgresql/jdbc2/AbstractJdbc2Statement.java b/org/postgresql/jdbc2/AbstractJdbc2Statement.java
index bacb941..57d6c87 100644
--- a/org/postgresql/jdbc2/AbstractJdbc2Statement.java
+++ b/org/postgresql/jdbc2/AbstractJdbc2Statement.java
@@ -3,7 +3,7 @@
* Copyright (c) 2004-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
-* $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java,v 1.84.2.2 2006/01/30 20:10:41 jurka Exp $
+* $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java,v 1.84.2.3 2006/02/01 18:52:30 jurka Exp $
*
*-------------------------------------------------------------------------
*/
@@ -138,8 +138,9 @@ public abstract class AbstractJdbc2Statement implements BaseStatement
this.preparedQuery = connection.getQueryExecutor().createParameterizedQuery(parsed_sql);
this.preparedParameters = preparedQuery.createParameterList();
- this.testReturn = new int[preparedParameters.getInParameterCount()+1];
- this.functionReturnType = new int[preparedParameters.getInParameterCount()+1];
+ int inParamCount = preparedParameters.getInParameterCount() + 1;
+ this.testReturn = new int[inParamCount];
+ this.functionReturnType = new int[inParamCount];
resultsettype = rsType;
@@ -366,27 +367,41 @@ public abstract class AbstractJdbc2Statement implements BaseStatement
// figure out how many columns
int cols = rs.getMetaData().getColumnCount();
- callResult = new Object[cols];
+
+ int outParameterCount = preparedParameters.getOutParameterCount() ;
+
+ if ( cols != outParameterCount )
+ throw new PSQLException(GT.tr("A CallableStatement was excecuted with an invalid number of parameters"),PSQLState.SYNTAX_ERROR);
+
+ // allocate enough space for all possible parameters without regard to in/out
+ callResult = new Object[preparedParameters.getParameterCount()+1];
// move them into the result set
- for ( int i=0; i < cols; i++)
+ for ( int i=0,j=0; i < cols; i++,j++)
{
- callResult[i] = rs.getObject(i+1);
- int columnType = rs.getMetaData().getColumnType(1);
- if (columnType != functionReturnType[i])
+ // find the next out parameter, the assumption is that the functionReturnType
+ // array will be initialized with 0 and only out parameters will have values
+ // other than 0. 0 is the value for java.sql.Types.NULL, which should not
+ // conflict
+ while( j< functionReturnType.length && functionReturnType[j]==0) j++;
+
+ callResult[j] = rs.getObject(i+1);
+ int columnType = rs.getMetaData().getColumnType(i+1);
+
+ if (columnType != functionReturnType[j])
{
// this is here for the sole purpose of passing the cts
- if ( columnType == Types.DOUBLE && functionReturnType[i] == Types.REAL )
+ if ( columnType == Types.DOUBLE && functionReturnType[j] == Types.REAL )
{
// return it as a float
- if ( callResult[i] != null)
- callResult[i] = new Float(((Double)callResult[i]).floatValue());
+ if ( callResult[j] != null)
+ callResult[j] = new Float(((Double)callResult[j]).floatValue());
}
else
{
- throw new PSQLException (GT.tr("A CallableStatement function was executed and the return was of type {0} however type {1} was registered.",
- new Object[]{
- "java.sql.Types=" + columnType, "java.sql.Types=" + functionReturnType[i] }),
+ throw new PSQLException (GT.tr("A CallableStatement function was executed and the out parameter {0} was of type {1} however type {2} was registered.",
+ new Object[]{""+i+1,
+ "java.sql.Types=" + columnType, "java.sql.Types=" + functionReturnType[j] }),
PSQLState.DATA_TYPE_MISMATCH);
}
}
diff --git a/org/postgresql/test/jdbc3/Jdbc3CallableStatementTest.java b/org/postgresql/test/jdbc3/Jdbc3CallableStatementTest.java
index 298747f..86167f0 100644
--- a/org/postgresql/test/jdbc3/Jdbc3CallableStatementTest.java
+++ b/org/postgresql/test/jdbc3/Jdbc3CallableStatementTest.java
@@ -11,10 +11,12 @@ import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import org.postgresql.test.TestUtil;
+import org.postgresql.util.PSQLState;
import junit.framework.TestCase;
@@ -26,6 +28,7 @@ import junit.framework.TestCase;
*/
public class Jdbc3CallableStatementTest extends TestCase
{
+
Connection con;
/* (non-Javadoc)
@@ -37,8 +40,10 @@ public class Jdbc3CallableStatementTest extends TestCase
Statement stmt = con.createStatement ();
stmt.execute("create temp table numeric_tab (MAX_VAL NUMERIC(30,15), MIN_VAL NUMERIC(30,15), NULL_VAL NUMERIC(30,15) NULL)");
stmt.execute("insert into numeric_tab values ( 999999999999999,0.000000000000001, null)");
+ stmt.execute("CREATE OR REPLACE FUNCTION myiofunc(a INOUT int, b OUT int) AS 'BEGIN b := a; a := 1; END;' LANGUAGE plpgsql");
+ stmt.execute("CREATE OR REPLACE FUNCTION myif(a INOUT int, b IN int) AS 'BEGIN a := b; END;' LANGUAGE plpgsql");
- boolean ret = stmt.execute("create or replace function "
+ stmt.execute("create or replace function "
+ "Numeric_Proc( OUT IMAX NUMERIC(30,15), OUT IMIN NUMERIC(30,15), OUT INUL NUMERIC(30,15)) as "
+ "'begin "
+ "select max_val into imax from numeric_tab;"
@@ -48,7 +53,34 @@ public class Jdbc3CallableStatementTest extends TestCase
+ " end;' "
+ "language 'plpgsql';");
+ stmt.execute( "CREATE OR REPLACE FUNCTION test_somein_someout("
+ + "pa IN int4,"
+ + "pb OUT varchar,"
+ + "pc OUT int8)"
+ + " AS "
+
+ + "'begin "
+ + "pb := ''out'';"
+ + "pc := pa + 1;"
+ + "end;'"
+ + "LANGUAGE 'plpgsql' VOLATILE;"
+
+ );
+ stmt.execute("CREATE OR REPLACE FUNCTION test_allinout("
+ + "pa INOUT int4,"
+ + "pb INOUT varchar,"
+ + "pc INOUT int8)"
+ + " AS "
+ + "'begin "
+ + "pa := pa + 1;"
+ + "pb := ''foo out'';"
+ + "pc := pa + 1;"
+ + "end;'"
+ + "LANGUAGE 'plpgsql' VOLATILE;"
+ );
+
+
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
@@ -57,14 +89,82 @@ public class Jdbc3CallableStatementTest extends TestCase
{
Statement stmt = con.createStatement();
stmt.execute("drop function Numeric_Proc(out decimal, out decimal, out decimal)");
+ stmt.execute("drop function test_somein_someout(int4)");
+ stmt.execute("drop function test_allinout( inout int4, inout varchar, inout int8)");
+ stmt.execute("drop function myiofunc(a INOUT int, b OUT int) ");
+ stmt.execute("drop function myif(a INOUT int, b IN int)");
stmt.close();
}
+ public void testSomeInOut() throws Throwable
+ {
+
+
+ CallableStatement call = con.prepareCall( "{ call test_somein_someout(?,?,?) }" ) ;
+
+ call.registerOutParameter(2,Types.VARCHAR);
+ call.registerOutParameter(3,Types.BIGINT);
+ call.setInt(1,20);
+ call.execute();
- public void testNumeric() throws Throwable
+ }
+ public void testNotEnoughParameters() throws Throwable
+ {
+
+ CallableStatement cs = con.prepareCall("{call myiofunc(?,?)}");
+ cs.setInt(1,2);
+ cs.registerOutParameter(2,Types.INTEGER);
+ try
+ {
+ cs.execute();
+ fail("Should throw an exception ");
+ }
+ catch( SQLException ex)
+ {
+ assertTrue(ex.getSQLState().equalsIgnoreCase(PSQLState.SYNTAX_ERROR.getState()));
+ }
+
+ }
+ public void testTooManyParameters() throws Throwable
{
+
+ CallableStatement cs = con.prepareCall("{call myif(?,?)}");
try
{
+ cs.setInt(1,1);
+ cs.setInt(2,2);
+ cs.registerOutParameter(1,Types.INTEGER);
+ cs.registerOutParameter(2,Types.INTEGER);
+ cs.execute();
+ fail("should throw an exception");
+ }
+ catch( SQLException ex )
+ {
+ assertTrue(ex.getSQLState().equalsIgnoreCase(PSQLState.SYNTAX_ERROR.getState()));
+ }
+
+ }
+ public void testAllInOut() throws Throwable
+ {
+
+ CallableStatement call = con.prepareCall( "{ call test_allinout(?,?,?) }" ) ;
+
+ call.registerOutParameter(1,Types.INTEGER);
+ call.registerOutParameter(2,Types.VARCHAR);
+ call.registerOutParameter(3,Types.BIGINT);
+ call.setInt(1,20);
+ call.setString(2,"hi");
+ call.setInt(3,123);
+ call.execute();
+ call.getInt(1);
+ call.getString(2);
+ call.getLong(3);
+
+ }
+
+ public void testNumeric() throws Throwable
+ {
+
CallableStatement call = con.prepareCall( "{ call Numeric_Proc(?,?,?) }" ) ;
call.registerOutParameter(1,Types.NUMERIC,15);
@@ -78,7 +178,7 @@ public class Jdbc3CallableStatementTest extends TestCase
ret=call.getBigDecimal(2);
assertTrue ("correct return from getNumeric ()",
- ret.equals (new java.math.BigDecimal("0.000000000000001")));
+ ret.equals (new java.math.BigDecimal("0.000000000000001")));
try
{
ret = call.getBigDecimal(3);
@@ -87,28 +187,26 @@ public class Jdbc3CallableStatementTest extends TestCase
assertTrue("This should be null",call.wasNull());
}
- }
- catch(Exception ex)
- {
- fail(ex.getMessage());
- }
+
+
}
public void testGetObjectDecimal() throws Throwable
{
try
{
- Statement stmt = con.createStatement();
- stmt.execute("create temp table decimal_tab ( max_val numeric(30,15), min_val numeric(30,15), nul_val numeric(30,15) )");
- stmt.execute("insert into decimal_tab values (999999999999999.000000000000000,0.000000000000001,null)");
- boolean ret = stmt.execute("create or replace function "
- + "decimal_proc( OUT pmax numeric, OUT pmin numeric, OUT nval numeric) as "
- + "'begin "
- + "select max_val into pmax from decimal_tab;"
- + "select min_val into pmin from decimal_tab;"
- + "select nul_val into nval from decimal_tab;"
-
- + " end;' "
- + "language 'plpgsql';");
+ Statement stmt = con.createStatement();
+ stmt.execute("create temp table decimal_tab ( max_val numeric(30,15), min_val numeric(30,15), nul_val numeric(30,15) )");
+ stmt.execute("insert into decimal_tab values (999999999999999.000000000000000,0.000000000000001,null)");
+
+ boolean ret = stmt.execute("create or replace function "
+ + "decimal_proc( OUT pmax numeric, OUT pmin numeric, OUT nval numeric) as "
+ + "'begin "
+ + "select max_val into pmax from decimal_tab;"
+ + "select min_val into pmin from decimal_tab;"
+ + "select nul_val into nval from decimal_tab;"
+
+ + " end;' "
+ + "language 'plpgsql';");
}
catch (Exception ex)
{
@@ -234,10 +332,7 @@ public class Jdbc3CallableStatementTest extends TestCase
cstmt.getBoolean(3);
assertTrue(cstmt.wasNull());
}
- catch ( Exception ex )
- {
- fail(ex.getMessage());
- }
+
finally
{
try
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libpostgresql-jdbc-java.git
More information about the pkg-java-commits
mailing list