mirror of
https://github.com/postgres/postgres.git
synced 2025-07-15 19:21:59 +03:00
JDBC checkin fixing the following bugs:
Fixed support in the driver for notifications (added PGConnection.getNotifications()) - problem reported by Benjamin.Feinstein@guardent.com Worked around server problems with int8/int2 and constants; quote values when they are intended to bind to an int8/int2 column - reported by many Fixed bug in the Array interface with string parsing not handling escaped characters correctly - reported by devajx@yahoo.com Added workaround to support 'infinity' and '-infinity' for dates - reported bydmitry@openratings.com Fixed some performance issues with setBlob - reported by d.wall@computer.org Added support for using new prepared statements functionality in 7.3 (added PGStatement.setUseServerPrepare() and isUseServerPrepare() methods) Modified Files: jdbc/org/postgresql/PGConnection.java jdbc/org/postgresql/PGStatement.java jdbc/org/postgresql/core/QueryExecutor.java jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java jdbc/org/postgresql/jdbc2/Array.java Added Files: jdbc/org/postgresql/PGNotification.java jdbc/org/postgresql/core/Notification.java
This commit is contained in:
@ -8,7 +8,7 @@ import java.util.Vector;
|
||||
import org.postgresql.largeobject.*;
|
||||
import org.postgresql.util.*;
|
||||
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.5 2002/08/23 20:45:49 barry Exp $
|
||||
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.6 2002/09/02 03:07:36 barry Exp $
|
||||
* This class defines methods of the jdbc1 specification. This class is
|
||||
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
|
||||
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
|
||||
@ -44,7 +44,13 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
|
||||
//Used by the preparedstatement style methods
|
||||
protected String[] m_sqlFragments;
|
||||
private String[] m_origSqlFragments;
|
||||
private String[] m_executeSqlFragments;
|
||||
protected Object[] m_binds = new Object[0];
|
||||
private String[] m_bindTypes = new String[0];
|
||||
private String m_statementName = null;
|
||||
private boolean m_useServerPrepare = false;
|
||||
private static int m_preparedCount = 1;
|
||||
|
||||
//Used by the callablestatement style methods
|
||||
private static final String JDBC_SYNTAX = "{[? =] call <some_function> ([? [,?]*]) }";
|
||||
@ -102,11 +108,13 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
|
||||
m_sqlFragments = new String[v.size()];
|
||||
m_binds = new String[v.size() - 1];
|
||||
m_bindTypes = new String[v.size() - 1];
|
||||
//BJL why if binds is new???
|
||||
clearParameters();
|
||||
|
||||
for (i = 0 ; i < m_sqlFragments.length; ++i)
|
||||
m_sqlFragments[i] = (String)v.elementAt(i);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -207,6 +215,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
throw new PSQLException("postgresql.call.noreturntype");
|
||||
if (isFunction) { // set entry 1 to dummy entry..
|
||||
m_binds[0] = ""; // dummy entry which ensured that no one overrode
|
||||
m_bindTypes[0] = PG_TEXT;
|
||||
// and calls to setXXX (2,..) really went to first arg in a function call..
|
||||
}
|
||||
|
||||
@ -220,6 +229,53 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
rs.close();
|
||||
}
|
||||
|
||||
//Use server prepared statements if directed
|
||||
if (m_useServerPrepare) {
|
||||
if (m_statementName == null) {
|
||||
m_statementName = "JDBC_STATEMENT_" + m_preparedCount++;
|
||||
m_origSqlFragments = new String[m_sqlFragments.length];
|
||||
m_executeSqlFragments = new String[m_sqlFragments.length];
|
||||
System.arraycopy(m_sqlFragments, 0, m_origSqlFragments, 0, m_sqlFragments.length);
|
||||
m_executeSqlFragments[0] = "EXECUTE " + m_statementName;
|
||||
if (m_sqlFragments.length > 1) {
|
||||
m_executeSqlFragments[0] = m_executeSqlFragments[0] + "(";
|
||||
for(int i = 1; i < m_bindTypes.length; i++) {
|
||||
m_executeSqlFragments[i] = ", ";
|
||||
}
|
||||
m_executeSqlFragments[m_bindTypes.length] = ")";
|
||||
}
|
||||
synchronized (sbuf) {
|
||||
sbuf.setLength(0);
|
||||
sbuf.append("PREPARE ");
|
||||
sbuf.append(m_statementName);
|
||||
if (m_origSqlFragments.length > 1) {
|
||||
sbuf.append("(");
|
||||
for(int i = 0; i < m_bindTypes.length - 1; i++) {
|
||||
sbuf.append(m_bindTypes[i]);
|
||||
sbuf.append(", ");
|
||||
}
|
||||
sbuf.append(m_bindTypes[m_bindTypes.length - 1]);
|
||||
sbuf.append(")");
|
||||
}
|
||||
sbuf.append(" AS ");
|
||||
sbuf.append(m_origSqlFragments[0]);
|
||||
for(int i = 1; i < m_origSqlFragments.length; i++) {
|
||||
sbuf.append(" $");
|
||||
sbuf.append(i);
|
||||
sbuf.append(" ");
|
||||
sbuf.append(m_origSqlFragments[i]);
|
||||
}
|
||||
sbuf.append("; ");
|
||||
|
||||
sbuf.append(m_executeSqlFragments[0]);
|
||||
m_sqlFragments[0] = sbuf.toString();
|
||||
System.arraycopy(m_executeSqlFragments, 1, m_sqlFragments, 1, m_sqlFragments.length - 1);
|
||||
}
|
||||
|
||||
} else {
|
||||
m_sqlFragments = m_executeSqlFragments;
|
||||
}
|
||||
}
|
||||
|
||||
// New in 7.1, pass Statement so that ExecSQL can customise to it
|
||||
result = ((AbstractJdbc1Connection)connection).ExecSQL(m_sqlFragments, m_binds, (java.sql.Statement)this);
|
||||
@ -618,7 +674,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
*/
|
||||
public void setNull(int parameterIndex, int sqlType) throws SQLException
|
||||
{
|
||||
set(parameterIndex, "null");
|
||||
bind(parameterIndex, "null", PG_TEXT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -631,7 +687,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
*/
|
||||
public void setBoolean(int parameterIndex, boolean x) throws SQLException
|
||||
{
|
||||
set(parameterIndex, x ? "'t'" : "'f'");
|
||||
bind(parameterIndex, x ? "'t'" : "'f'", PG_BOOLEAN);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -644,7 +700,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
*/
|
||||
public void setByte(int parameterIndex, byte x) throws SQLException
|
||||
{
|
||||
set(parameterIndex, Integer.toString(x));
|
||||
bind(parameterIndex, Integer.toString(x), PG_TEXT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -657,7 +713,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
*/
|
||||
public void setShort(int parameterIndex, short x) throws SQLException
|
||||
{
|
||||
set(parameterIndex, Integer.toString(x));
|
||||
//Note this should be fixed
|
||||
//as soon as the backend correctly supports int8 type
|
||||
//comparisons
|
||||
bind(parameterIndex,"'" + Integer.toString(x) +"'", PG_INT2);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -670,7 +729,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
*/
|
||||
public void setInt(int parameterIndex, int x) throws SQLException
|
||||
{
|
||||
set(parameterIndex, Integer.toString(x));
|
||||
bind(parameterIndex, Integer.toString(x), PG_INTEGER);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -683,7 +742,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
*/
|
||||
public void setLong(int parameterIndex, long x) throws SQLException
|
||||
{
|
||||
set(parameterIndex, Long.toString(x));
|
||||
//Note this should be fixed
|
||||
//as soon as the backend correctly supports int8 type
|
||||
//comparisons
|
||||
bind(parameterIndex, "'"+Long.toString(x)+"'", PG_INT8);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -696,7 +758,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
*/
|
||||
public void setFloat(int parameterIndex, float x) throws SQLException
|
||||
{
|
||||
set(parameterIndex, Float.toString(x));
|
||||
//Note this should be fixed
|
||||
//as soon as the backend correctly supports int8 type
|
||||
//comparisons
|
||||
bind(parameterIndex, "'"+Float.toString(x)+"'", PG_FLOAT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -709,7 +774,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
*/
|
||||
public void setDouble(int parameterIndex, double x) throws SQLException
|
||||
{
|
||||
set(parameterIndex, Double.toString(x));
|
||||
//Note this should be fixed
|
||||
//as soon as the backend correctly supports int8 type
|
||||
//comparisons
|
||||
bind(parameterIndex, "'"+Double.toString(x)+"'", PG_DOUBLE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -727,7 +795,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
setNull(parameterIndex, Types.OTHER);
|
||||
else
|
||||
{
|
||||
set(parameterIndex, x.toString());
|
||||
//Note this should be fixed
|
||||
//as soon as the backend correctly supports int8 type
|
||||
//comparisons
|
||||
bind(parameterIndex, "'"+x.toString()+"'", PG_NUMERIC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -742,6 +813,11 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public void setString(int parameterIndex, String x) throws SQLException
|
||||
{
|
||||
setString(parameterIndex, x, PG_TEXT);
|
||||
}
|
||||
|
||||
public void setString(int parameterIndex, String x, String type) throws SQLException
|
||||
{
|
||||
// if the passed string is null, then set this column to null
|
||||
if (x == null)
|
||||
@ -765,7 +841,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
sbuf.append(c);
|
||||
}
|
||||
sbuf.append('\'');
|
||||
set(parameterIndex, sbuf.toString());
|
||||
bind(parameterIndex, sbuf.toString(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -795,7 +871,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
}
|
||||
else
|
||||
{
|
||||
setString(parameterIndex, PGbytea.toPGString(x));
|
||||
setString(parameterIndex, PGbytea.toPGString(x), PG_TEXT);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -826,7 +902,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
}
|
||||
else
|
||||
{
|
||||
set(parameterIndex, "'" + x.toString() + "'");
|
||||
bind(parameterIndex, "'" + x.toString() + "'", PG_DATE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -846,7 +922,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
}
|
||||
else
|
||||
{
|
||||
set(parameterIndex, "'" + x.toString() + "'");
|
||||
bind(parameterIndex, "'" + x.toString() + "'", PG_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
@ -932,7 +1008,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
sbuf.append(l_minos);
|
||||
}
|
||||
sbuf.append("'");
|
||||
set(parameterIndex, sbuf.toString());
|
||||
bind(parameterIndex, sbuf.toString(), PG_TIMESTAMPTZ);
|
||||
}
|
||||
|
||||
}
|
||||
@ -969,7 +1045,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
InputStreamReader l_inStream = new InputStreamReader(x, "ASCII");
|
||||
char[] l_chars = new char[length];
|
||||
int l_charsRead = l_inStream.read(l_chars, 0, length);
|
||||
setString(parameterIndex, new String(l_chars, 0, l_charsRead));
|
||||
setString(parameterIndex, new String(l_chars, 0, l_charsRead), PG_TEXT);
|
||||
}
|
||||
catch (UnsupportedEncodingException l_uee)
|
||||
{
|
||||
@ -1018,7 +1094,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
InputStreamReader l_inStream = new InputStreamReader(x, "UTF-8");
|
||||
char[] l_chars = new char[length];
|
||||
int l_charsRead = l_inStream.read(l_chars, 0, length);
|
||||
setString(parameterIndex, new String(l_chars, 0, l_charsRead));
|
||||
setString(parameterIndex, new String(l_chars, 0, l_charsRead), PG_TEXT);
|
||||
}
|
||||
catch (UnsupportedEncodingException l_uee)
|
||||
{
|
||||
@ -1130,8 +1206,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < m_binds.length ; i++)
|
||||
for (i = 0 ; i < m_binds.length ; i++) {
|
||||
m_binds[i] = null;
|
||||
m_bindTypes[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1162,9 +1240,11 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
}
|
||||
switch (targetSqlType)
|
||||
{
|
||||
case Types.INTEGER:
|
||||
bind(parameterIndex, x.toString(), PG_INTEGER);
|
||||
break;
|
||||
case Types.TINYINT:
|
||||
case Types.SMALLINT:
|
||||
case Types.INTEGER:
|
||||
case Types.BIGINT:
|
||||
case Types.REAL:
|
||||
case Types.FLOAT:
|
||||
@ -1172,9 +1252,12 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
case Types.DECIMAL:
|
||||
case Types.NUMERIC:
|
||||
if (x instanceof Boolean)
|
||||
set(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0");
|
||||
bind(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0", PG_BOOLEAN);
|
||||
else
|
||||
set(parameterIndex, x.toString());
|
||||
//Note this should be fixed
|
||||
//as soon as the backend correctly supports int8 type
|
||||
//comparisons
|
||||
bind(parameterIndex, "'"+x.toString()+"'", PG_NUMERIC);
|
||||
break;
|
||||
case Types.CHAR:
|
||||
case Types.VARCHAR:
|
||||
@ -1193,7 +1276,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
case Types.BIT:
|
||||
if (x instanceof Boolean)
|
||||
{
|
||||
set(parameterIndex, ((Boolean)x).booleanValue() ? "TRUE" : "FALSE");
|
||||
bind(parameterIndex, ((Boolean)x).booleanValue() ? "TRUE" : "FALSE", PG_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1205,7 +1288,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
setObject(parameterIndex, x);
|
||||
break;
|
||||
case Types.OTHER:
|
||||
setString(parameterIndex, ((PGobject)x).getValue());
|
||||
setString(parameterIndex, ((PGobject)x).getValue(), PG_TEXT);
|
||||
break;
|
||||
default:
|
||||
throw new PSQLException("postgresql.prep.type");
|
||||
@ -1255,7 +1338,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
else if (x instanceof Boolean)
|
||||
setBoolean(parameterIndex, ((Boolean)x).booleanValue());
|
||||
else if (x instanceof PGobject)
|
||||
setString(parameterIndex, ((PGobject)x).getValue());
|
||||
setString(parameterIndex, ((PGobject)x).getValue(), PG_TEXT);
|
||||
else
|
||||
// Try to store java object in database
|
||||
setSerialize(parameterIndex, connection.storeObject(x), x.getClass().getName() );
|
||||
@ -1579,13 +1662,14 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
* @param s a string to be stored
|
||||
* @exception SQLException if something goes wrong
|
||||
*/
|
||||
protected void set(int paramIndex, String s) throws SQLException
|
||||
protected void bind(int paramIndex, Object s, String type) throws SQLException
|
||||
{
|
||||
if (paramIndex < 1 || paramIndex > m_binds.length)
|
||||
throw new PSQLException("postgresql.prep.range");
|
||||
if (paramIndex == 1 && isFunction) // need to registerOut instead
|
||||
throw new PSQLException ("postgresql.call.funcover");
|
||||
m_binds[paramIndex - 1] = s;
|
||||
m_bindTypes[paramIndex - 1] = type;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1607,7 +1691,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
// This cannot be just a plain OID because then there would be ambiguity
|
||||
// between when you want the oid itself and when you want the object
|
||||
// an oid references.
|
||||
set(parameterIndex, Long.toString(x) + "::" + tablename );
|
||||
bind(parameterIndex, Long.toString(x) + "::" + tablename, PG_TEXT );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1675,4 +1759,27 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setUseServerPrepare(boolean flag) {
|
||||
m_useServerPrepare = flag;
|
||||
}
|
||||
|
||||
public boolean isUseServerPrepare() {
|
||||
return m_useServerPrepare;
|
||||
}
|
||||
|
||||
|
||||
private static final String PG_TEXT = "text";
|
||||
private static final String PG_INTEGER = "integer";
|
||||
private static final String PG_INT2 = "int2";
|
||||
private static final String PG_INT8 = "int8";
|
||||
private static final String PG_NUMERIC = "numeric";
|
||||
private static final String PG_FLOAT = "float";
|
||||
private static final String PG_DOUBLE = "double";
|
||||
private static final String PG_BOOLEAN = "boolean";
|
||||
private static final String PG_DATE = "date";
|
||||
private static final String PG_TIME = "time";
|
||||
private static final String PG_TIMESTAMPTZ = "timestamptz";
|
||||
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user