Applied patch from Oliver Jowett to clean up some instances where the wrong

type was being reported for PREPAREs.

 Modified Files:
 	jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
 	jdbc/org/postgresql/test/jdbc2/ServerPreparedStmtTest.java
This commit is contained in:
Barry Lind 2003-09-18 04:14:27 +00:00
parent 7da6afef26
commit 215d965f0e
2 changed files with 96 additions and 31 deletions

View File

@ -26,7 +26,7 @@ import java.sql.Timestamp;
import java.sql.Types; import java.sql.Types;
import java.util.Vector; import java.util.Vector;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.37 2003/09/17 05:07:37 barry Exp $ /* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.38 2003/09/18 04:14:27 barry Exp $
* This class defines methods of the jdbc1 specification. This class is * This class defines methods of the jdbc1 specification. This class is
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2 * extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement * methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
@ -893,6 +893,9 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
case Types.TIMESTAMP: case Types.TIMESTAMP:
l_pgType = PG_TIMESTAMPTZ; l_pgType = PG_TIMESTAMPTZ;
break; break;
case Types.BIT:
l_pgType = PG_BOOLEAN;
break;
case Types.BINARY: case Types.BINARY:
case Types.VARBINARY: case Types.VARBINARY:
case Types.LONGVARBINARY: case Types.LONGVARBINARY:
@ -930,7 +933,7 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
*/ */
public void setByte(int parameterIndex, byte x) throws SQLException public void setByte(int parameterIndex, byte x) throws SQLException
{ {
bind(parameterIndex, Integer.toString(x), PG_TEXT); bind(parameterIndex, Integer.toString(x), PG_INT2);
} }
/* /*
@ -1457,6 +1460,21 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
} }
} }
// Helper method that extracts numeric values from an arbitary Object.
private String numericValueOf(Object x)
{
if (x instanceof Boolean)
return ((Boolean)x).booleanValue() ? "1" :"0";
else if (x instanceof Integer || x instanceof Long ||
x instanceof Double || x instanceof Short ||
x instanceof Number || x instanceof Float)
return x.toString();
else
//ensure the value is a valid numeric value to avoid
//sql injection attacks
return new BigDecimal(x.toString()).toString();
}
/* /*
* Set the value of a parameter using an object; use the java.lang * Set the value of a parameter using an object; use the java.lang
* equivalent objects for integral values. * equivalent objects for integral values.
@ -1486,35 +1504,25 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
switch (targetSqlType) switch (targetSqlType)
{ {
case Types.INTEGER: case Types.INTEGER:
if (x instanceof Boolean) bind(parameterIndex, numericValueOf(x), PG_INTEGER);
bind(parameterIndex,((Boolean)x).booleanValue() ? "1" :"0", PG_BOOLEAN);
else if (x instanceof Integer || x instanceof Long ||
x instanceof Double || x instanceof Short ||
x instanceof Number || x instanceof Float )
bind(parameterIndex, x.toString(), PG_INTEGER);
else
//ensure the value is a valid numeric value to avoid
//sql injection attacks
bind(parameterIndex, new BigDecimal(x.toString()).toString(), PG_INTEGER);
break; break;
case Types.TINYINT: case Types.TINYINT:
case Types.SMALLINT: case Types.SMALLINT:
bind(parameterIndex, numericValueOf(x), PG_INT2);
break;
case Types.BIGINT: case Types.BIGINT:
bind(parameterIndex, numericValueOf(x), PG_INT8);
break;
case Types.REAL: case Types.REAL:
case Types.FLOAT: case Types.FLOAT:
bind(parameterIndex, numericValueOf(x), PG_FLOAT);
break;
case Types.DOUBLE: case Types.DOUBLE:
bind(parameterIndex, numericValueOf(x), PG_DOUBLE);
break;
case Types.DECIMAL: case Types.DECIMAL:
case Types.NUMERIC: case Types.NUMERIC:
if (x instanceof Boolean) bind(parameterIndex, numericValueOf(x), PG_NUMERIC);
bind(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0", PG_BOOLEAN);
else if (x instanceof Integer || x instanceof Long ||
x instanceof Double || x instanceof Short ||
x instanceof Number || x instanceof Float )
bind(parameterIndex, x.toString(), PG_NUMERIC);
else
//ensure the value is a valid numeric value to avoid
//sql injection attacks
bind(parameterIndex, new BigDecimal(x.toString()).toString(), PG_NUMERIC);
break; break;
case Types.CHAR: case Types.CHAR:
case Types.VARCHAR: case Types.VARCHAR:
@ -1559,7 +1567,7 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
} }
else if (x instanceof Number) else if (x instanceof Number)
{ {
bind(parameterIndex, ((Number)x).intValue()==1 ? "'1'" : "'0'", PG_BOOLEAN); bind(parameterIndex, ((Number)x).intValue()!=0 ? "'1'" : "'0'", PG_BOOLEAN);
} }
else else
{ {
@ -1572,7 +1580,10 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
setObject(parameterIndex, x); setObject(parameterIndex, x);
break; break;
case Types.OTHER: case Types.OTHER:
setString(parameterIndex, ((PGobject)x).getValue(), PG_TEXT); if (x instanceof PGobject)
setString(parameterIndex, ((PGobject)x).getValue(), ((PGobject)x).getType());
else
throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE);
break; break;
default: default:
throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE); throw new PSQLException("postgresql.prep.type", PSQLState.INVALID_PARAMETER_TYPE);

View File

@ -26,14 +26,14 @@ public class ServerPreparedStmtTest extends TestCase
con = TestUtil.openDB(); con = TestUtil.openDB();
Statement stmt = con.createStatement(); Statement stmt = con.createStatement();
TestUtil.createTable(con, "testsps", "id integer"); TestUtil.createTable(con, "testsps", "id integer, value boolean");
stmt.executeUpdate("INSERT INTO testsps VALUES (1)"); stmt.executeUpdate("INSERT INTO testsps VALUES (1,'t')");
stmt.executeUpdate("INSERT INTO testsps VALUES (2)"); stmt.executeUpdate("INSERT INTO testsps VALUES (2,'t')");
stmt.executeUpdate("INSERT INTO testsps VALUES (3)"); stmt.executeUpdate("INSERT INTO testsps VALUES (3,'t')");
stmt.executeUpdate("INSERT INTO testsps VALUES (4)"); stmt.executeUpdate("INSERT INTO testsps VALUES (4,'t')");
stmt.executeUpdate("INSERT INTO testsps VALUES (6)"); stmt.executeUpdate("INSERT INTO testsps VALUES (6,'t')");
stmt.executeUpdate("INSERT INTO testsps VALUES (9)"); stmt.executeUpdate("INSERT INTO testsps VALUES (9,'f')");
stmt.close(); stmt.close();
} }
@ -125,6 +125,60 @@ public class ServerPreparedStmtTest extends TestCase
pstmt.close(); pstmt.close();
} }
// Verify we can bind booleans-as-objects ok.
public void testBooleanObjectBind() throws Exception
{
PreparedStatement pstmt = con.prepareStatement("SELECT * FROM testsps WHERE value = ?");
((PGStatement)pstmt).setUseServerPrepare(true);
if (TestUtil.haveMinimumServerVersion(con,"7.3")) {
assertTrue(((PGStatement)pstmt).isUseServerPrepare());
} else {
assertTrue(!((PGStatement)pstmt).isUseServerPrepare());
}
pstmt.setObject(1, new Boolean(false), java.sql.Types.BIT);
ResultSet rs = pstmt.executeQuery();
assertTrue(rs.next());
assertEquals(9, rs.getInt(1));
rs.close();
}
// Verify we can bind booleans-as-integers ok.
public void testBooleanIntegerBind() throws Exception
{
PreparedStatement pstmt = con.prepareStatement("SELECT * FROM testsps WHERE id = ?");
((PGStatement)pstmt).setUseServerPrepare(true);
if (TestUtil.haveMinimumServerVersion(con,"7.3")) {
assertTrue(((PGStatement)pstmt).isUseServerPrepare());
} else {
assertTrue(!((PGStatement)pstmt).isUseServerPrepare());
}
pstmt.setObject(1, new Boolean(true), java.sql.Types.INTEGER);
ResultSet rs = pstmt.executeQuery();
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
rs.close();
}
// Verify we can bind booleans-as-native-types ok.
public void testBooleanBind() throws Exception
{
PreparedStatement pstmt = con.prepareStatement("SELECT * FROM testsps WHERE value = ?");
((PGStatement)pstmt).setUseServerPrepare(true);
if (TestUtil.haveMinimumServerVersion(con,"7.3")) {
assertTrue(((PGStatement)pstmt).isUseServerPrepare());
} else {
assertTrue(!((PGStatement)pstmt).isUseServerPrepare());
}
pstmt.setBoolean(1, false);
ResultSet rs = pstmt.executeQuery();
assertTrue(rs.next());
assertEquals(9, rs.getInt(1));
rs.close();
}
public void testPreparedStatementsWithBinds() throws Exception public void testPreparedStatementsWithBinds() throws Exception
{ {
PreparedStatement pstmt = con.prepareStatement("SELECT * FROM testsps WHERE id = ? or id = ?"); PreparedStatement pstmt = con.prepareStatement("SELECT * FROM testsps WHERE id = ? or id = ?");