diff options
author | Barry Lind <barry@xythos.com> | 2003-02-04 09:20:12 +0000 |
---|---|---|
committer | Barry Lind <barry@xythos.com> | 2003-02-04 09:20:12 +0000 |
commit | 16a30346c86590fbdcd83cacd2a0a9dbd2cd00dc (patch) | |
tree | a555d2560764362bf58c0081187607c9094e1510 | |
parent | 2d1f94054259d3237e678d89ca9e57305a6a3997 (diff) | |
download | postgresql-16a30346c86590fbdcd83cacd2a0a9dbd2cd00dc.tar.gz postgresql-16a30346c86590fbdcd83cacd2a0a9dbd2cd00dc.zip |
Patch from Nic Ferrier to add support for result sets being cursor based
so that rows can be fetched incrementally. This is enabled by using
setFetchSize()
26 files changed, 428 insertions, 231 deletions
diff --git a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java index a97638a890e..7193a8a615e 100644 --- a/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java +++ b/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java @@ -6,6 +6,9 @@ import java.io.IOException; import java.sql.*; import org.postgresql.*; import org.postgresql.util.PSQLException; +import org.postgresql.jdbc1.AbstractJdbc1Connection; +import org.postgresql.jdbc1.AbstractJdbc1ResultSet; +import org.postgresql.jdbc1.AbstractJdbc1Statement; /* * Executes a query on the backend. @@ -13,36 +16,70 @@ import org.postgresql.util.PSQLException; * <p>The lifetime of a QueryExecutor object is from sending the query * until the response has been received from the backend. * - * $Id: QueryExecutor.java,v 1.17 2002/11/14 05:35:45 barry Exp $ + * $Id: QueryExecutor.java,v 1.18 2003/02/04 09:20:08 barry Exp $ */ public class QueryExecutor { + //This version of execute does not take an existing result set, but + //creates a new one for the results of the query + public static ResultSet execute (String[] p_sqlFrags, + Object[] p_binds, + java.sql.Statement statement) + throws SQLException + { + QueryExecutor qe = new QueryExecutor(); + qe.m_sqlFrags = p_sqlFrags; + qe.m_binds = p_binds; + qe.statement = statement; + if (statement != null) + qe.maxRows = statement.getMaxRows(); + else + qe.maxRows = 0; - private final String[] m_sqlFrags; - private final Object[] m_binds; - private final java.sql.Statement statement; - private final PG_Stream pg_stream; - private final org.postgresql.jdbc1.AbstractJdbc1Connection connection; + qe.connection = (AbstractJdbc1Connection)((AbstractJdbc1Statement)statement).getPGConnection(); + qe.pg_stream = qe.connection.getPGStream(); - public QueryExecutor(String[] p_sqlFrags, Object[] p_binds, - java.sql.Statement statement, - PG_Stream pg_stream, - java.sql.Connection connection) + return qe.execute(); + } + + //This version of execute reuses an existing result set for the query + //results, this is used when a result set is backed by a cursor and + //more results are fetched + public static void execute (String[] p_sqlFrags, + Object[] p_binds, + java.sql.ResultSet rs) throws SQLException { - this.m_sqlFrags = p_sqlFrags; - this.m_binds = p_binds; - this.statement = statement; - this.pg_stream = pg_stream; - this.connection = (org.postgresql.jdbc1.AbstractJdbc1Connection)connection; - - if (statement != null) - maxRows = statement.getMaxRows(); + QueryExecutor qe = new QueryExecutor(); + qe.m_sqlFrags = p_sqlFrags; + qe.m_binds = p_binds; + qe.rs = rs; + qe.statement = (java.sql.Statement)((AbstractJdbc1ResultSet)qe.rs).getPGStatement(); + if (qe.statement != null) + qe.maxRows = qe.statement.getMaxRows(); else - maxRows = 0; + qe.maxRows = 0; + + qe.connection = (AbstractJdbc1Connection)((AbstractJdbc1Statement)qe.statement).getPGConnection(); + qe.pg_stream = qe.connection.getPGStream(); + + qe.execute(); } + + private QueryExecutor () + { + } + + private String[] m_sqlFrags; + private Object[] m_binds; + private java.sql.Statement statement; + private java.sql.ResultSet rs; + + private AbstractJdbc1Connection connection; + private PG_Stream pg_stream; + private Field[] fields = null; private Vector tuples = new Vector(); private boolean binaryCursor = false; @@ -51,10 +88,12 @@ public class QueryExecutor private long insert_oid = 0; private int maxRows; + /* * Execute a query on the backend. + * */ - public java.sql.ResultSet execute() throws SQLException + private java.sql.ResultSet execute() throws SQLException { StringBuffer errorMessage = null; @@ -130,7 +169,18 @@ public class QueryExecutor if ( errorMessage != null ) throw new SQLException( errorMessage.toString() ); - return connection.getResultSet(statement, fields, tuples, status, update_count, insert_oid, binaryCursor); + + //if an existing result set was passed in reuse it, else + //create a new one + if (rs != null) + { + ((org.postgresql.jdbc1.AbstractJdbc1ResultSet)rs).reInit(fields, tuples, status, update_count, insert_oid, binaryCursor); + } + else + { + rs = ((AbstractJdbc1Statement)statement).createResultSet(fields, tuples, status, update_count, insert_oid, binaryCursor); + } + return rs; } } @@ -145,10 +195,12 @@ public class QueryExecutor for (int i = 0 ; i < m_binds.length ; ++i) { if (m_binds[i] == null) - throw new PSQLException("postgresql.prep.param", new Integer(i + 1)); + throw new PSQLException("postgresql.prep.param (" + i + ")", new Integer(i + 1)); + pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[i])); pg_stream.Send(connection.getEncoding().encode(m_binds[i].toString())); } + pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[m_binds.length])); pg_stream.SendChar(0); pg_stream.flush(); diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java index e22cf53144d..d7ba1b273d5 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java @@ -14,7 +14,7 @@ import org.postgresql.largeobject.LargeObjectManager; import org.postgresql.util.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.13 2002/11/14 05:35:45 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.14 2003/02/04 09:20:08 barry Exp $ * This class defines methods of the jdbc1 specification. This class is * extended by org.postgresql.jdbc2.AbstractJdbc2Connection which adds the jdbc2 * methods. The real Connection class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Connection @@ -22,8 +22,12 @@ import org.postgresql.util.*; public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnection { // This is the network stream associated with this connection - public PG_Stream pg_stream; + private PG_Stream pg_stream; + public PG_Stream getPGStream() { + return pg_stream; + } + protected String PG_HOST; protected int PG_PORT; protected String PG_USER; @@ -84,7 +88,6 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec public abstract java.sql.Statement createStatement() throws SQLException; - /* * This method actually opens the connection. It is called by Driver. * @@ -350,9 +353,10 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec // Set datestyle and fetch db encoding in a single call, to avoid making // more than one round trip to the backend during connection startup. - java.sql.ResultSet resultSet = - ExecSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";"); + java.sql.ResultSet resultSet + = execSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";"); + if (! resultSet.next()) { throw new PSQLException("postgresql.con.failed", "failed getting backend encoding"); @@ -373,7 +377,7 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec if (haveMinimumServerVersion("7.3")) { java.sql.ResultSet acRset = - ExecSQL("set client_encoding = 'UNICODE'; show autocommit"); + execSQL("set client_encoding = 'UNICODE'; show autocommit"); //set encoding to be unicode encoding = Encoding.getEncoding("UNICODE", null); @@ -388,7 +392,7 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec //to make the setting permanent if (acRset.getString(1).equals("off")) { - ExecSQL("set autocommit = on; commit;"); + execSQL("set autocommit = on; commit;"); } } @@ -409,13 +413,6 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec return this_driver; } - // These methods used to be in the main Connection implementation. As they - // are common to all implementations (JDBC1 or 2), they are placed here. - // This should make it easy to maintain the two specifications. - - public abstract java.sql.ResultSet getResultSet(Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException; - - public abstract java.sql.ResultSet getResultSet(Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount) throws SQLException; /* * This adds a warning to the warning chain. @@ -445,64 +442,15 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec //} } - /* - * Send a query to the backend. Returns one of the ResultSet - * objects. - * - * <B>Note:</B> there does not seem to be any method currently - * in existance to return the update count. - * - * @param sql the SQL statement to be executed - * @return a ResultSet holding the results - * @exception SQLException if a database error occurs + /** Simple query execution. */ - public java.sql.ResultSet ExecSQL(String sql) throws SQLException + public java.sql.ResultSet execSQL (String s) throws SQLException { - return ExecSQL(sql, null); - } - - /* - * Send a query to the backend. Returns one of the ResultSet - * objects. - * - * <B>Note:</B> there does not seem to be any method currently - * in existance to return the update count. - * - * @param sql the SQL statement to be executed - * @param stat The Statement associated with this query (may be null) - * @return a ResultSet holding the results - * @exception SQLException if a database error occurs - */ - public java.sql.ResultSet ExecSQL(String sql, java.sql.Statement stat) throws SQLException - { - if (isClosed()) - { - throw new PSQLException("postgresql.con.closed"); - } - return new QueryExecutor(new String[] {sql}, EMPTY_OBJECT_ARRAY, stat, pg_stream, (java.sql.Connection)this).execute(); - } - private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; - - /* - * Send a query to the backend. Returns one of the ResultSet - * objects. - * - * <B>Note:</B> there does not seem to be any method currently - * in existance to return the update count. - * - * @param p_sqlFragmentss the SQL statement parts to be executed - * @param p_binds the SQL bind values - * @param stat The Statement associated with this query (may be null) - * @return a ResultSet holding the results - * @exception SQLException if a database error occurs - */ - public java.sql.ResultSet ExecSQL(String[] p_sqlFragments, Object[] p_binds, java.sql.Statement stat) throws SQLException - { - if (isClosed()) - { - throw new PSQLException("postgresql.con.closed"); - } - return new QueryExecutor(p_sqlFragments, p_binds, stat, pg_stream, (java.sql.Connection)this).execute(); + final Object[] nullarr = new Object[0]; + java.sql.Statement stat = createStatement(); + return QueryExecutor.execute(new String[] { s }, + nullarr, + stat); } /* @@ -939,27 +887,27 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec //We do the select to ensure a transaction is in process //before we do the commit to avoid warning messages //from issuing a commit without a transaction in process - ExecSQL("select 1; commit; set autocommit = on;"); + execSQL("select 1; commit; set autocommit = on;"); } else { - ExecSQL("end"); + execSQL("end"); } } else { if (haveMinimumServerVersion("7.3")) { - ExecSQL("set autocommit = off; " + getIsolationLevelSQL()); + execSQL("set autocommit = off; " + getIsolationLevelSQL()); } else if (haveMinimumServerVersion("7.1")) { - ExecSQL("begin;" + getIsolationLevelSQL()); + execSQL("begin;" + getIsolationLevelSQL()); } else { - ExecSQL("begin"); - ExecSQL(getIsolationLevelSQL()); + execSQL("begin"); + execSQL(getIsolationLevelSQL()); } } this.autoCommit = autoCommit; @@ -993,17 +941,17 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec return ; if (haveMinimumServerVersion("7.3")) { - ExecSQL("commit; " + getIsolationLevelSQL()); + execSQL("commit; " + getIsolationLevelSQL()); } else if (haveMinimumServerVersion("7.1")) { - ExecSQL("commit;begin;" + getIsolationLevelSQL()); + execSQL("commit;begin;" + getIsolationLevelSQL()); } else { - ExecSQL("commit"); - ExecSQL("begin"); - ExecSQL(getIsolationLevelSQL()); + execSQL("commit"); + execSQL("begin"); + execSQL(getIsolationLevelSQL()); } } @@ -1024,17 +972,17 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec //we don't automatically start a transaction //but let the server functionality automatically start //one when the first statement is executed - ExecSQL("rollback; " + getIsolationLevelSQL()); + execSQL("rollback; " + getIsolationLevelSQL()); } else if (haveMinimumServerVersion("7.1")) { - ExecSQL("rollback; begin;" + getIsolationLevelSQL()); + execSQL("rollback; begin;" + getIsolationLevelSQL()); } else { - ExecSQL("rollback"); - ExecSQL("begin"); - ExecSQL(getIsolationLevelSQL()); + execSQL("rollback"); + execSQL("begin"); + execSQL(getIsolationLevelSQL()); } } @@ -1049,14 +997,14 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec String sql = "show transaction isolation level"; String level = null; if (haveMinimumServerVersion("7.3")) { - ResultSet rs = ExecSQL(sql); + ResultSet rs = execSQL(sql); if (rs.next()) { level = rs.getString(1); } rs.close(); } else { clearWarnings(); - ExecSQL(sql); + execSQL(sql); SQLWarning warning = getWarnings(); if (warning != null) { @@ -1121,7 +1069,7 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec new Integer(isolationLevel)); } } - ExecSQL(isolationLevelSQL); + execSQL(isolationLevelSQL); } /* @@ -1264,7 +1212,7 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec } else { sql = "SELECT typname FROM pg_type WHERE oid = " +oid; } - ResultSet result = ExecSQL(sql); + ResultSet result = execSQL(sql); if (((AbstractJdbc1ResultSet)result).getColumnCount() != 1 || ((AbstractJdbc1ResultSet)result).getTupleCount() != 1) { throw new PSQLException("postgresql.unexpected"); } @@ -1305,7 +1253,7 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec } else { sql = "SELECT oid FROM pg_type WHERE typname='" + typeName + "'"; } - ResultSet result = ExecSQL(sql); + ResultSet result = execSQL(sql); if (((AbstractJdbc1ResultSet)result).getColumnCount() != 1 || ((AbstractJdbc1ResultSet)result).getTupleCount() != 1) throw new PSQLException("postgresql.unexpected"); result.next(); @@ -1413,21 +1361,21 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec * Tip: keep these grouped together by the Types. value */ private static final int jdbc1Typei[] = { - Types.SMALLINT, - Types.INTEGER, Types.INTEGER, - Types.BIGINT, - Types.DOUBLE, Types.DOUBLE, - Types.NUMERIC, - Types.REAL, - Types.DOUBLE, - Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.BINARY, - Types.BIT, - Types.DATE, - Types.TIME, - Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP - }; + Types.SMALLINT, + Types.INTEGER, Types.INTEGER, + Types.BIGINT, + Types.DOUBLE, Types.DOUBLE, + Types.NUMERIC, + Types.REAL, + Types.DOUBLE, + Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.BINARY, + Types.BIT, + Types.DATE, + Types.TIME, + Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP + }; //Methods to support postgres notifications public void addNotification(org.postgresql.PGNotification p_notification) diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java index a1a61a58cce..9e217f7f24f 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java @@ -1915,7 +1915,7 @@ public abstract class AbstractJdbc1DatabaseMetaData } rs.close(); - return connection.getResultSet(null, f, v, "OK", 1); + return ((AbstractJdbc1Statement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); } /* @@ -2206,7 +2206,8 @@ public abstract class AbstractJdbc1DatabaseMetaData tuple[0] = types[i].getBytes(); v.addElement(tuple); } - return connection.getResultSet(null, f, v, "OK", 1); + + return ((AbstractJdbc1Statement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); } /* @@ -2380,7 +2381,7 @@ public abstract class AbstractJdbc1DatabaseMetaData } rs.close(); - return connection.getResultSet(null, f, v, "OK", 1); + return ((AbstractJdbc1Statement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); } /* @@ -2492,7 +2493,8 @@ public abstract class AbstractJdbc1DatabaseMetaData } } rs.close(); - return connection.getResultSet(null, f, v, "OK", 1); + + return ((AbstractJdbc1Statement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); } /* @@ -2594,7 +2596,7 @@ public abstract class AbstractJdbc1DatabaseMetaData } rs.close(); - return connection.getResultSet(null, f, v, "OK", 1); + return ((AbstractJdbc1Statement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); } private static void sortStringArray(String s[]) { @@ -2787,7 +2789,8 @@ public abstract class AbstractJdbc1DatabaseMetaData tuple[7] = Integer.toString(java.sql.DatabaseMetaData.bestRowNotPseudo).getBytes(); v.addElement(tuple); } - return connection.getResultSet(null, f, v, "OK", 1); + + return ((AbstractJdbc1Statement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); } /* @@ -2857,7 +2860,7 @@ public abstract class AbstractJdbc1DatabaseMetaData /* Perhaps we should check that the given * catalog.schema.table actually exists. -KJ */ - return connection.getResultSet(null, f, v, "OK", 1); + return ((AbstractJdbc1Statement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); } /* @@ -3180,7 +3183,7 @@ public abstract class AbstractJdbc1DatabaseMetaData tuples.addElement(tuple); } - return connection.getResultSet(null, f, tuples, "OK", 1); + return ((AbstractJdbc1Statement)connection.createStatement()).createResultSet(f, tuples, "OK", 1, 0, false); } /* @@ -3465,7 +3468,8 @@ public abstract class AbstractJdbc1DatabaseMetaData v.addElement(tuple); } rs.close(); - return connection.getResultSet(null, f, v, "OK", 1); + + return ((AbstractJdbc1Statement)connection.createStatement()).createResultSet(f, v, "OK", 1, 0, false); } /* diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java index 48e8b8f70bb..7c029353d5f 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java @@ -13,16 +13,21 @@ import org.postgresql.largeobject.*; import org.postgresql.util.PGbytea; import org.postgresql.util.PSQLException; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.8 2003/01/14 09:13:51 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.9 2003/02/04 09:20:08 barry Exp $ * This class defines methods of the jdbc1 specification. This class is * extended by org.postgresql.jdbc2.AbstractJdbc2ResultSet which adds the jdbc2 * methods. The real ResultSet class (for jdbc1) is org.postgresql.jdbc1.Jdbc1ResultSet */ -public abstract class AbstractJdbc1ResultSet +public abstract class AbstractJdbc1ResultSet { protected Vector rows; // The results protected Statement statement; + + public org.postgresql.PGStatement getPGStatement() { + return (org.postgresql.PGStatement) statement; + } + protected Field fields[]; // The field descriptions protected String status; // Status of the result protected boolean binaryCursor = false; // is the data binary or Strings @@ -42,14 +47,21 @@ public abstract class AbstractJdbc1ResultSet public byte[][] rowBuffer = null; - public AbstractJdbc1ResultSet(org.postgresql.PGConnection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) + public AbstractJdbc1ResultSet(Statement statement, + Field[] fields, + Vector tuples, + String status, + int updateCount, + long insertOID, + boolean binaryCursor) { - this.connection = conn; + this.connection = ((org.postgresql.jdbc1.AbstractJdbc1Statement)statement).getPGConnection(); this.statement = statement; this.fields = fields; this.rows = tuples; this.status = status; this.updateCount = updateCount; + this.insertOID = insertOID; this.this_row = null; this.current_row = -1; @@ -57,13 +69,53 @@ public abstract class AbstractJdbc1ResultSet } + //method to reinitialize a result set with more data + public void reInit (Field[] fields, Vector tuples, String status, + int updateCount, long insertOID, boolean binaryCursor) + { + this.fields = fields; + // on a reinit the size of this indicates how many we pulled + // back. If it's 0 then the res set has ended. + this.rows = tuples; + this.status = status; + this.updateCount = updateCount; + this.insertOID = insertOID; + this.this_row = null; + this.current_row = -1; + this.binaryCursor = binaryCursor; + } + + public boolean next() throws SQLException { if (rows == null) throw new PSQLException("postgresql.con.closed"); if (++current_row >= rows.size()) - return false; + { + int fetchSize = ((AbstractJdbc1Statement)statement).fetchSize; + // Must be false if we weren't batching. + if (fetchSize == 0) + return false; + // Use the ref to the statement to get + // the details we need to do another cursor + // query - it will use reinit() to repopulate this + // with the right data. + String[] sql = new String[1]; + String[] binds = new String[0]; + // Is this the correct query??? + String cursorName = ((AbstractJdbc1Statement)statement).m_statementName; + sql[0] = "FETCH FORWARD " + fetchSize + " FROM " + cursorName; + org.postgresql.core.QueryExecutor.execute(sql, + binds, + (java.sql.ResultSet)this); + + // Test the new rows array. + if (rows.size() == 0) + return false; + // Otherwise reset the counter and let it go on... + current_row = 0; + } this_row = (byte [][])rows.elementAt(current_row); diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java index 2aeb5323db0..bf91cf14c9e 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java @@ -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.14 2002/11/20 07:34:32 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.15 2003/02/04 09:20:08 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 @@ -19,12 +19,19 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme // The connection who created us protected AbstractJdbc1Connection connection; + public org.postgresql.PGConnection getPGConnection() { + return connection; + } + /** The warnings chain. */ protected SQLWarning warnings = null; /** Maximum number of rows to return, 0 = unlimited */ protected int maxrows = 0; + /** Number of rows to get in a batch. */ + protected int fetchSize = 0; + /** Timeout (in seconds) for a query (not used) */ protected int timeout = 0; @@ -47,8 +54,10 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme private String[] m_origSqlFragments; private String[] m_executeSqlFragments; protected Object[] m_binds = new Object[0]; + protected String[] m_bindTypes = new String[0]; - private String m_statementName = null; + protected String m_statementName = null; + private boolean m_useServerPrepare = false; private static int m_preparedCount = 1; @@ -67,6 +76,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme protected Object callResult; + public abstract java.sql.ResultSet createResultSet(org.postgresql.Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException; public AbstractJdbc1Statement (AbstractJdbc1Connection connection) { @@ -117,7 +127,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme } - + /* * Execute a SQL statement that retruns a single ResultSet * @@ -132,11 +142,21 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme m_binds = new Object[0]; //If we have already created a server prepared statement, we need //to deallocate the existing one - if (m_statementName != null) { - ((AbstractJdbc1Connection)connection).ExecSQL("DEALLOCATE " + m_statementName); - m_statementName = null; - m_origSqlFragments = null; - m_executeSqlFragments = null; + if (m_statementName != null) + { + try + { + ((AbstractJdbc1Connection)connection).execSQL("DEALLOCATE " + m_statementName); + } + catch (Exception e) + { + } + finally + { + m_statementName = null; + m_origSqlFragments = null; + m_executeSqlFragments = null; + } } return executeQuery(); } @@ -150,7 +170,11 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public java.sql.ResultSet executeQuery() throws SQLException { - this.execute(); + if (fetchSize > 0) + this.executeWithCursor(); + else + this.execute(); + while (result != null && !((AbstractJdbc1ResultSet)result).reallyResultSet()) result = ((AbstractJdbc1ResultSet)result).getNext(); if (result == null) @@ -175,7 +199,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme //If we have already created a server prepared statement, we need //to deallocate the existing one if (m_statementName != null) { - ((AbstractJdbc1Connection)connection).ExecSQL("DEALLOCATE " + m_statementName); + ((AbstractJdbc1Connection)connection).execSQL("DEALLOCATE " + m_statementName); m_statementName = null; m_origSqlFragments = null; m_executeSqlFragments = null; @@ -219,7 +243,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme //If we have already created a server prepared statement, we need //to deallocate the existing one if (m_statementName != null) { - ((AbstractJdbc1Connection)connection).ExecSQL("DEALLOCATE " + m_statementName); + ((AbstractJdbc1Connection)connection).execSQL("DEALLOCATE " + m_statementName); m_statementName = null; m_origSqlFragments = null; m_executeSqlFragments = null; @@ -317,7 +341,9 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme } // 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); + result = org.postgresql.core.QueryExecutor.execute(m_sqlFragments, + m_binds, + (java.sql.Statement)this); //If we are executing a callable statement function set the return data if (isFunction) @@ -341,6 +367,102 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme } } + /** version of execute which converts the query to a cursor. + */ + public boolean executeWithCursor() throws SQLException + { + if (isFunction && !returnTypeSet) + 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.. + } + + // New in 7.1, if we have a previous resultset then force it to close + // This brings us nearer to compliance, and helps memory management. + // Internal stuff will call ExecSQL directly, bypassing this. + if (result != null) + { + java.sql.ResultSet rs = getResultSet(); + if (rs != null) + rs.close(); + } + + // I've pretty much ignored server prepared statements... can declare and prepare be + // used together? + // It's trivial to change this: you just have to resolve this issue + // of how to work out whether there's a function call. If there isn't then the first + // element of the array must be the bit that you extend to become the cursor + // decleration. + // The last thing that can go wrong is when the user supplies a cursor statement + // directly: the translation takes no account of that. I think we should just look + // for declare and stop the translation if we find it. + + // The first thing to do is transform the statement text into the cursor form. + String[] origSqlFragments = m_sqlFragments; + m_sqlFragments = new String[origSqlFragments.length]; + System.arraycopy(origSqlFragments, 0, m_sqlFragments, 0, origSqlFragments.length); + // Pinch the prepared count for our own nefarious purposes. + m_statementName = "JDBC_CURS_" + m_preparedCount++; + // The static bit to prepend to all querys. + String cursDecl = "BEGIN; DECLARE " + m_statementName + " CURSOR FOR "; + String endCurs = " FETCH FORWARD " + fetchSize + " FROM " + m_statementName + ";"; + + // Add the real query to the curs decleration. + // This is the bit that really makes the presumption about + // m_sqlFragments not being a function call. + if (m_sqlFragments.length < 1) + m_sqlFragments[0] = cursDecl + "SELECT NULL;"; + + else if (m_sqlFragments.length < 2) + { + if (m_sqlFragments[0].endsWith(";")) + m_sqlFragments[0] = cursDecl + m_sqlFragments[0] + endCurs; + else + m_sqlFragments[0] = cursDecl + m_sqlFragments[0] + ";" + endCurs; + } + else + { + m_sqlFragments[0] = cursDecl + m_sqlFragments[0]; + if (m_sqlFragments[m_sqlFragments.length - 1].endsWith(";")) + m_sqlFragments[m_sqlFragments.length - 1] += endCurs; + else + m_sqlFragments[m_sqlFragments.length - 1] += (";" + endCurs); + } + + result = org.postgresql.core.QueryExecutor.execute(m_sqlFragments, + m_binds, + (java.sql.Statement)this); + + //If we are executing a callable statement function set the return data + if (isFunction) + { + if (!((AbstractJdbc1ResultSet)result).reallyResultSet()) + throw new PSQLException("postgresql.call.noreturnval"); + if (!result.next ()) + throw new PSQLException ("postgresql.call.noreturnval"); + callResult = result.getObject(1); + int columnType = result.getMetaData().getColumnType(1); + if (columnType != functionReturnType) + { + Object[] arr = + { "java.sql.Types=" + columnType, + "java.sql.Types=" + functionReturnType + }; + throw new PSQLException ("postgresql.call.wrongrtntype",arr); + } + result.close (); + return true; + } + else + { + return (result != null && ((AbstractJdbc1ResultSet)result).reallyResultSet()); + } + } + + /* * setCursorName defines the SQL cursor name that will be used by * subsequent execute methods. This name can then be used in SQL @@ -593,7 +715,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme // If using server prepared statements deallocate them if (m_useServerPrepare && m_statementName != null) { - ((AbstractJdbc1Connection)connection).ExecSQL("DEALLOCATE " + m_statementName); + ((AbstractJdbc1Connection)connection).execSQL("DEALLOCATE " + m_statementName); } // Disasociate it from us (For Garbage Collection) @@ -1690,7 +1812,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme */ public byte[] getBytes(int parameterIndex) throws SQLException { - checkIndex (parameterIndex, Types.VARBINARY, "Bytes"); + checkIndex (parameterIndex, Types.VARBINARY, Types.BINARY, "Bytes"); return ((byte [])callResult); } @@ -1847,7 +1969,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme String l_sql = p_sql; int index = l_sql.indexOf ("="); // is implied func or proc? boolean isValid = true; - if (index != -1) + if (index > -1) { isFunction = true; isValid = l_sql.indexOf ("?") < index; // ? before = @@ -1875,12 +1997,25 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme // sure that the parameter numbers are the same as in the original // sql we add a dummy parameter in this case l_sql = (isFunction ? "?" : "") + l_sql.substring (index + 4); - l_sql = "select " + l_sql + " as " + RESULT_COLUMN + ";"; return l_sql; } /** helperfunction for the getXXX calls to check isFunction and index == 1 + * Compare BOTH type fields against the return type. + */ + protected void checkIndex (int parameterIndex, int type1, int type2, String getName) + throws SQLException + { + checkIndex (parameterIndex); + if (type1 != this.testReturn && type2 != this.testReturn) + throw new PSQLException("postgresql.call.wrongget", + new Object[]{"java.sql.Types=" + testReturn, + getName, + "java.sql.Types=" + type1}); + } + + /** helperfunction for the getXXX calls to check isFunction and index == 1 */ protected void checkIndex (int parameterIndex, int type, String getName) throws SQLException @@ -1888,10 +2023,11 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme checkIndex (parameterIndex); if (type != this.testReturn) throw new PSQLException("postgresql.call.wrongget", - new Object[]{"java.sql.Types=" + testReturn, - getName, - "java.sql.Types=" + type}); + new Object[]{"java.sql.Types=" + testReturn, + getName, + "java.sql.Types=" + type}); } + /** helperfunction for the getXXX calls to check isFunction and index == 1 * @param parameterIndex index of getXXX (index) * check to make sure is a function and index == 1 @@ -1912,7 +2048,7 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme //If turning server prepared statements off deallocate statement //and reset statement name if (m_useServerPrepare != flag && !flag) - ((AbstractJdbc1Connection)connection).ExecSQL("DEALLOCATE " + m_statementName); + ((AbstractJdbc1Connection)connection).execSQL("DEALLOCATE " + m_statementName); m_statementName = null; m_useServerPrepare = flag; } else { diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java index 7cd69103bd5..c79cea0d492 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1CallableStatement.java @@ -10,5 +10,10 @@ public class Jdbc1CallableStatement extends AbstractJdbc1Statement implements ja { super(connection, sql); } + + public java.sql.ResultSet createResultSet (org.postgresql.Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java index 3ddb071008d..9ee64f7db49 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java @@ -6,7 +6,7 @@ import java.sql.*; import org.postgresql.Field; import org.postgresql.util.PSQLException; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Connection.java,v 1.5 2002/09/06 21:23:06 momjian Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Connection.java,v 1.6 2003/02/04 09:20:10 barry Exp $ * This class implements the java.sql.Connection interface for JDBC1. * However most of the implementation is really done in * org.postgresql.jdbc1.AbstractJdbc1Connection @@ -36,16 +36,6 @@ public class Jdbc1Connection extends org.postgresql.jdbc1.AbstractJdbc1Connectio return metadata; } - public java.sql.ResultSet getResultSet(java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException - { - return new Jdbc1ResultSet(this, stat, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public java.sql.ResultSet getResultSet(java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException - { - return new Jdbc1ResultSet(this, stat, fields, tuples, status, updateCount, 0, false); - } - } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java index b065b572246..073185a5dac 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java @@ -11,4 +11,8 @@ public class Jdbc1PreparedStatement extends AbstractJdbc1Statement implements Pr super(connection, sql); } + public java.sql.ResultSet createResultSet (org.postgresql.Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java index 980bf872617..edc17ff13c9 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1ResultSet.java @@ -5,7 +5,7 @@ import java.sql.*; import java.util.Vector; import org.postgresql.Field; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1ResultSet.java,v 1.4 2002/09/06 21:23:06 momjian Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1ResultSet.java,v 1.5 2003/02/04 09:20:10 barry Exp $ * This class implements the java.sql.ResultSet interface for JDBC1. * However most of the implementation is really done in * org.postgresql.jdbc1.AbstractJdbc1ResultSet @@ -13,9 +13,9 @@ import org.postgresql.Field; public class Jdbc1ResultSet extends org.postgresql.jdbc1.AbstractJdbc1ResultSet implements java.sql.ResultSet { - public Jdbc1ResultSet(Jdbc1Connection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) + public Jdbc1ResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) { - super(conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); + super(statement, fields, tuples, status, updateCount, insertOID, binaryCursor); } public java.sql.ResultSetMetaData getMetaData() throws SQLException diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java index 2b3f521cc9a..ab5ba110c1f 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java @@ -3,7 +3,7 @@ package org.postgresql.jdbc1; import java.sql.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.3 2002/09/06 21:23:06 momjian Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.4 2003/02/04 09:20:10 barry Exp $ * This class implements the java.sql.Statement interface for JDBC1. * However most of the implementation is really done in * org.postgresql.jdbc1.AbstractJdbc1Statement @@ -16,4 +16,8 @@ public class Jdbc1Statement extends org.postgresql.jdbc1.AbstractJdbc1Statement super(c); } + public java.sql.ResultSet createResultSet (org.postgresql.Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc1ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java index d5476161ed5..45d18c5cb12 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java @@ -6,7 +6,7 @@ import java.net.ConnectException; import java.sql.*; import org.postgresql.util.PSQLException; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Connection.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Connection.java,v 1.3 2003/02/04 09:20:10 barry Exp $ * This class defines methods of the jdbc2 specification. This class extends * org.postgresql.jdbc1.AbstractJdbc1Connection which provides the jdbc1 * methods. The real Connection class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Connection @@ -17,7 +17,7 @@ public abstract class AbstractJdbc2Connection extends org.postgresql.jdbc1.Abstr * The current type mappings */ protected java.util.Map typemap; - + public java.sql.Statement createStatement() throws SQLException { // The spec says default of TYPE_FORWARD_ONLY but everyone is used to diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java index 3d53fe3fd0a..aef0baf6c9d 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java @@ -15,7 +15,7 @@ import org.postgresql.util.PGbytea; import org.postgresql.util.PSQLException; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.12 2003/01/23 18:49:22 davec Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.13 2003/02/04 09:20:10 barry Exp $ * This class defines methods of the jdbc2 specification. This class extends * org.postgresql.jdbc1.AbstractJdbc1ResultSet which provides the jdbc1 * methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2ResultSet @@ -38,11 +38,10 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra protected PreparedStatement deleteStatement = null; private PreparedStatement selectStatement = null; - - - public AbstractJdbc2ResultSet(org.postgresql.PGConnection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) + + public AbstractJdbc2ResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) { - super (conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); + super (statement, fields, tuples, status, updateCount, insertOID, binaryCursor); } public java.net.URL getURL(int columnIndex) throws SQLException @@ -366,9 +365,7 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra public int getFetchSize() throws SQLException { - // In this implementation we return the entire result set, so - // here return the number of rows we have. Sub-classes can return a proper - // value + // Returning the current batch size seems the right thing to do. return rows.size(); } @@ -754,7 +751,6 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra } updateValue(columnIndex, theData); - } @@ -787,7 +783,6 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra throw new PSQLException("postgresql.updateable.ioerror" + ie); } updateValue(columnIndex, theData); - } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java index f439f95a4dd..615d323c1d1 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java @@ -8,7 +8,7 @@ import java.util.Vector; import org.postgresql.largeobject.*; import org.postgresql.util.PSQLException; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.10 2002/11/20 20:37:53 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.11 2003/02/04 09:20:10 barry Exp $ * This class defines methods of the jdbc2 specification. This class extends * org.postgresql.jdbc1.AbstractJdbc1Statement which provides the jdbc1 * methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Statement @@ -133,7 +133,7 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra public int getFetchSize() throws SQLException { - return 0; + return super.fetchSize; } public int getResultSetConcurrency() throws SQLException @@ -148,12 +148,14 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra public void setFetchDirection(int direction) throws SQLException { - throw org.postgresql.Driver.notImplemented(); + // I don't think this should happen, since it's a hint it should just + // fail quietly. + // throw org.postgresql.Driver.notImplemented(); } public void setFetchSize(int rows) throws SQLException { - throw org.postgresql.Driver.notImplemented(); + super.fetchSize = rows; } public void setResultSetConcurrency(int value) throws SQLException diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java index cfaecc972b1..54f59532603 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java @@ -343,7 +343,8 @@ public class Array implements java.sql.Array default: throw org.postgresql.Driver.notImplemented(); } - return ((AbstractJdbc2Connection)conn).getResultSet(null, fields, rows, "OK", 1 ); + java.sql.Statement stat = ((AbstractJdbc2Connection)conn).createStatement(); + return ((AbstractJdbc2Statement)stat).createResultSet(fields, rows, "OK", 1, 0, false); } public String toString() diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java index 46ff83a1e0c..72dc7ed66e9 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2CallableStatement.java @@ -11,5 +11,9 @@ public class Jdbc2CallableStatement extends org.postgresql.jdbc2.AbstractJdbc2St super(connection, sql); } + public java.sql.ResultSet createResultSet (org.postgresql.Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc2ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java index 6ebd0850fb7..0a7b7bbb757 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java @@ -6,7 +6,7 @@ import java.util.Vector; import java.util.Hashtable; import org.postgresql.Field; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Connection.java,v 1.5 2002/09/06 21:23:06 momjian Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Connection.java,v 1.6 2003/02/04 09:20:10 barry Exp $ * This class implements the java.sql.Connection interface for JDBC2. * However most of the implementation is really done in * org.postgresql.jdbc2.AbstractJdbc2Connection or one of it's parents @@ -46,17 +46,6 @@ public class Jdbc2Connection extends org.postgresql.jdbc2.AbstractJdbc2Connectio return metadata; } - public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException - { - return new Jdbc2ResultSet(this, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException - { - return new Jdbc2ResultSet(this, statement, fields, tuples, status, updateCount, 0, false); - } - - } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java index 15fd8d9a756..79f83d6a6be 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java @@ -11,5 +11,9 @@ public class Jdbc2PreparedStatement extends org.postgresql.jdbc2.AbstractJdbc2St super(connection, sql); } + public java.sql.ResultSet createResultSet (org.postgresql.Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc2ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java index 36e3aa048ec..ed7979faefc 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java @@ -5,7 +5,7 @@ import java.sql.*; import java.util.Vector; import org.postgresql.Field; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2ResultSet.java,v 1.6 2002/09/11 05:38:45 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2ResultSet.java,v 1.7 2003/02/04 09:20:10 barry Exp $ * This class implements the java.sql.ResultSet interface for JDBC2. * However most of the implementation is really done in * org.postgresql.jdbc2.AbstractJdbc2ResultSet or one of it's parents @@ -13,9 +13,9 @@ import org.postgresql.Field; public class Jdbc2ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet implements java.sql.ResultSet { - public Jdbc2ResultSet(Jdbc2Connection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) + public Jdbc2ResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) { - super(conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); + super(statement, fields, tuples, status, updateCount, insertOID, binaryCursor); } public java.sql.ResultSetMetaData getMetaData() throws SQLException diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java index ed894f6cd10..9d0548229c0 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java @@ -3,7 +3,7 @@ package org.postgresql.jdbc2; import java.sql.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Statement.java,v 1.3 2002/09/06 21:23:06 momjian Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Statement.java,v 1.4 2003/02/04 09:20:10 barry Exp $ * This class implements the java.sql.Statement interface for JDBC2. * However most of the implementation is really done in * org.postgresql.jdbc2.AbstractJdbc2Statement or one of it's parents @@ -16,4 +16,8 @@ public class Jdbc2Statement extends org.postgresql.jdbc2.AbstractJdbc2Statement super(c); } + public java.sql.ResultSet createResultSet (org.postgresql.Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc2ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); + } } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java index 4be956e0439..8b617fe436a 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java @@ -4,7 +4,7 @@ package org.postgresql.jdbc3; import java.sql.*; import java.util.Vector; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3ResultSet.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/AbstractJdbc3ResultSet.java,v 1.3 2003/02/04 09:20:10 barry Exp $ * This class defines methods of the jdbc3 specification. This class extends * org.postgresql.jdbc2.AbstractJdbc2ResultSet which provides the jdbc2 * methods. The real Statement class (for jdbc3) is org.postgresql.jdbc3.Jdbc3ResultSet @@ -12,9 +12,9 @@ import java.util.Vector; public abstract class AbstractJdbc3ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet { - public AbstractJdbc3ResultSet(org.postgresql.PGConnection conn, Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) + public AbstractJdbc3ResultSet(Statement statement, org.postgresql.Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) { - super (conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); + super (statement, fields, tuples, status, updateCount, insertOID, binaryCursor); } /** diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java index 64b2be2d41f..7cd509f794b 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3CallableStatement.java @@ -11,5 +11,10 @@ public class Jdbc3CallableStatement extends org.postgresql.jdbc3.AbstractJdbc3St super(connection, sql); } + public java.sql.ResultSet createResultSet (org.postgresql.Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc3ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); + } + } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java index 2e1ba7d8cbf..0685694b7ce 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java @@ -6,7 +6,7 @@ import java.util.Vector; import java.util.Hashtable; import org.postgresql.Field; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Connection.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Connection.java,v 1.3 2003/02/04 09:20:10 barry Exp $ * This class implements the java.sql.Connection interface for JDBC3. * However most of the implementation is really done in * org.postgresql.jdbc3.AbstractJdbc3Connection or one of it's parents @@ -46,16 +46,4 @@ public class Jdbc3Connection extends org.postgresql.jdbc3.AbstractJdbc3Connectio return metadata; } - public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException - { - return new Jdbc3ResultSet(this, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); - } - - public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException - { - return new Jdbc3ResultSet(this, statement, fields, tuples, status, updateCount, 0, false); - } - } - - diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java index 85ccbbb5e89..62d33925d82 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3PreparedStatement.java @@ -11,5 +11,10 @@ public class Jdbc3PreparedStatement extends org.postgresql.jdbc3.AbstractJdbc3St super(connection, sql); } + public java.sql.ResultSet createResultSet (org.postgresql.Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc3ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); + } + } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java index 4e53404e8a9..255f34b6b74 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java @@ -5,7 +5,7 @@ import java.sql.*; import java.util.Vector; import org.postgresql.Field; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3ResultSet.java,v 1.3 2002/09/11 05:38:45 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3ResultSet.java,v 1.4 2003/02/04 09:20:11 barry Exp $ * This class implements the java.sql.ResultSet interface for JDBC3. * However most of the implementation is really done in * org.postgresql.jdbc3.AbstractJdbc3ResultSet or one of it's parents @@ -13,9 +13,9 @@ import org.postgresql.Field; public class Jdbc3ResultSet extends org.postgresql.jdbc3.AbstractJdbc3ResultSet implements java.sql.ResultSet { - public Jdbc3ResultSet(Jdbc3Connection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) + public Jdbc3ResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) { - super(conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor); + super(statement, fields, tuples, status, updateCount, insertOID, binaryCursor); } public java.sql.ResultSetMetaData getMetaData() throws SQLException diff --git a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java index c711b11696b..bcac4501d47 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Statement.java @@ -3,7 +3,7 @@ package org.postgresql.jdbc3; import java.sql.*; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Statement.java,v 1.2 2002/09/06 21:23:06 momjian Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc3/Attic/Jdbc3Statement.java,v 1.3 2003/02/04 09:20:11 barry Exp $ * This class implements the java.sql.Statement interface for JDBC3. * However most of the implementation is really done in * org.postgresql.jdbc3.AbstractJdbc3Statement or one of it's parents @@ -16,4 +16,9 @@ public class Jdbc3Statement extends org.postgresql.jdbc3.AbstractJdbc3Statement super(c); } + public java.sql.ResultSet createResultSet (org.postgresql.Field[] fields, java.util.Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException + { + return new Jdbc3ResultSet(this, fields, tuples, status, updateCount, insertOID, binaryCursor); + } + } diff --git a/src/interfaces/jdbc/org/postgresql/util/Serialize.java b/src/interfaces/jdbc/org/postgresql/util/Serialize.java index 48d18ef02ee..d4bf01fb643 100644 --- a/src/interfaces/jdbc/org/postgresql/util/Serialize.java +++ b/src/interfaces/jdbc/org/postgresql/util/Serialize.java @@ -405,7 +405,7 @@ public class Serialize if (Driver.logDebug) Driver.debug("Serialize.store: " + sb.toString() ); - ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).ExecSQL(sb.toString()); + ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).execSQL(sb.toString()); // fetch the OID for returning if (update) |