Index: org/postgresql/PGConnection.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/PGConnection.java,v
retrieving revision 1.3
diff -u -r1.3 PGConnection.java
--- org/postgresql/PGConnection.java	2002/09/06 21:23:05	1.3
+++ org/postgresql/PGConnection.java	2002/12/11 14:13:31
@@ -14,6 +14,12 @@
  */
 public interface PGConnection
 {
+
+	/* Specify the method which all connections must provide.
+	 */
+	public void openConnection (String host, int port, Properties props,
+				    String database, String url, Driver driver)	throws SQLException;
+
 	/*
 	 * Get the character encoding to use for this connection.
 	 */
@@ -77,5 +83,21 @@
 	public PGNotification[] getNotifications();
 
 
+
+
+	// Added by Nic.
+
+	/** Create a result set for the specified statement.
+	 * This is the factory method provided by the various
+	 * version specific implementations of the JDBC connection
+	 * classes.
+	 */
+	public java.sql.ResultSet createResultSet (java.sql.Statement statement);
+
+	/** Create a result set wrapepd around an existing cursor.
+	 */
+	public PGRefCursorResultSet createRefCursorResultSet (java.sql.Statement statement, String cursorHandle) throws SQLException;
 }
+
+
 
Index: org/postgresql/PGRefCursorResultSet.java
===================================================================
RCS file: PGRefCursorResultSet.java
diff -N PGRefCursorResultSet.java
--- /dev/null	Wed Dec 11 09:09:00 2002
+++ PGRefCursorResultSet.java	Wed Dec 11 09:13:31 2002
@@ -0,0 +1,15 @@
+package org.postgresql;
+
+
+import java.util.Vector;
+
+
+/** PG base rep of a ref cursor based Res Set.
+ */
+public interface PGRefCursorResultSet
+{
+
+	// return the name of the cursor.
+	public String getRefCursor ();
+
+}
Index: org/postgresql/PGResultSet.java
===================================================================
RCS file: PGResultSet.java
diff -N PGResultSet.java
--- /dev/null	Wed Dec 11 09:09:00 2002
+++ PGResultSet.java	Wed Dec 11 09:13:31 2002
@@ -0,0 +1,16 @@
+package org.postgresql;
+
+
+import java.util.Vector;
+
+
+/** PG base rep of a Res Set.
+ */
+public interface PGResultSet
+{
+
+	/** The init method is what is used to put the data into a ResultSet.
+	 */
+	public void init (Field[] fields, Vector tuples, String status,
+			  int update_count, long insert_oid, boolean binaryCursor);
+}
Index: org/postgresql/core/QueryExecutor.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java,v
retrieving revision 1.16.2.1
diff -u -r1.16.2.1 QueryExecutor.java
--- org/postgresql/core/QueryExecutor.java	2002/11/14 05:54:39	1.16.2.1
+++ org/postgresql/core/QueryExecutor.java	2002/12/11 14:13:32
@@ -18,13 +18,57 @@
 
 public class QueryExecutor
 {
+	/** nic version - statically sets up the QE correctly.
+	 */
+	public static void execute (String[] p_sqlFrags,
+				    Object[] p_binds,
+				    java.sql.Statement statement,
+				    java.sql.ResultSet rs,
+				    PG_Stream pg_stream,
+				    java.sql.Connection con)
+	throws SQLException
+	{
+		QueryExecutor qe = new QueryExecutor();
+		// I think this should be a PGConnection and we should move
+		// everything we need for that from AbstractJdbc1... into PGConnection.
+		qe.connection = (org.postgresql.jdbc1.AbstractJdbc1Connection)con;
+		qe.m_sqlFrags = p_sqlFrags;
+		qe.m_binds = p_binds;
+		qe.statement = statement;
+		// Nic says: connection should wrap pg_stream.
+		qe.pg_stream = pg_stream;
+		if (statement != null)
+			qe.maxRows = statement.getMaxRows();
+		else
+			qe.maxRows = 0;
+		// The result set.
+		qe.rs = rs;
+		qe.execute();
+	}
+
+	// This is the result set used to wrap the results.
+	// The type of this is whatever is passed into the static above.
+	private java.sql.ResultSet rs;
+
+	// cons for the static above.
+	private QueryExecutor ()
+	{
+	}
+
+	
 
-	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;
 
+	/*** pre-nic implementation   ***/
+
+
+	/// Nic has removed the final from ALL of these (to facilitate static method).
+	private String[] m_sqlFrags;
+	private Object[] m_binds;
+	private java.sql.Statement statement;
+	private PG_Stream pg_stream;
+	private org.postgresql.jdbc1.AbstractJdbc1Connection connection;
+
+
 	public QueryExecutor(String[] p_sqlFrags, Object[] p_binds,
 						 java.sql.Statement statement,
 						 PG_Stream pg_stream,
@@ -33,7 +77,7 @@
 	{
 		this.m_sqlFrags = p_sqlFrags;
 		this.m_binds = p_binds;
-		this.statement = statement;
+		this.statement = statement;	
 		this.pg_stream = pg_stream;
 		this.connection = (org.postgresql.jdbc1.AbstractJdbc1Connection)connection;
 
@@ -43,6 +87,7 @@
 			maxRows = 0;
 	}
 
+
 	private Field[] fields = null;
 	private Vector tuples = new Vector();
 	private boolean binaryCursor = false;
@@ -51,8 +96,10 @@
 	private long insert_oid = 0;
 	private int maxRows;
 
+
 	/*
 	 * Execute a query on the backend.
+	 *
 	 */
 	public java.sql.ResultSet execute() throws SQLException
 	{
@@ -129,8 +176,13 @@
 			// did we get an error during this query?
 			if ( errorMessage != null )
 				throw new SQLException( errorMessage.toString() );
+
 
-			return connection.getResultSet(statement, fields, tuples, status, update_count, insert_oid, binaryCursor);
+			// Nic changes.
+			PGResultSet resSet = ((PGResultSet)rs);
+			//  System.out.println(getClass().getName() + " resSet=" + resSet);
+			resSet.init(fields, tuples, status, update_count, insert_oid, binaryCursor);
+			return rs;
 		}
 	}
 
@@ -145,10 +197,17 @@
 			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));
+
+				// System.out.println("QE send(" + m_sqlFrags[i] + ")");
+				// System.out.println("QE send(" + m_binds[i].toString() + ")");
+				
 				pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[i]));
 				pg_stream.Send(connection.getEncoding().encode(m_binds[i].toString()));
 			}
+
+			// System.out.println("QE send(" + m_sqlFrags[m_binds.length] + ")");
+
 			pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[m_binds.length]));
 			pg_stream.SendChar(0);
 			pg_stream.flush();
Index: org/postgresql/jdbc1/AbstractJdbc1Connection.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java,v
retrieving revision 1.12.2.1
diff -u -r1.12.2.1 AbstractJdbc1Connection.java
--- org/postgresql/jdbc1/AbstractJdbc1Connection.java	2002/11/14 05:54:39	1.12.2.1
+++ org/postgresql/jdbc1/AbstractJdbc1Connection.java	2002/12/11 14:13:33
@@ -23,7 +23,7 @@
 {
 	// This is the network stream associated with this connection
 	public PG_Stream pg_stream;
-
+  
 	protected String PG_HOST;
 	protected int PG_PORT;
 	protected String PG_USER;
@@ -84,7 +84,6 @@
 
 	public abstract java.sql.Statement createStatement() throws SQLException;
 
-
 	/*
 	 * This method actually opens the connection. It is called by Driver.
 	 *
@@ -350,9 +349,10 @@
 		// 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
+			= doQuery("set datestyle to 'ISO'; select version(), " + encodingQuery + ";");
+		
 		if (! resultSet.next())
 		{
 			throw new PSQLException("postgresql.con.failed", "failed getting backend encoding");
@@ -373,7 +373,7 @@
 		if (haveMinimumServerVersion("7.3")) 
 		{
 			java.sql.ResultSet acRset =
-				ExecSQL("set client_encoding = 'UNICODE'; show autocommit");
+				doQuery("set client_encoding = 'UNICODE'; show autocommit");
 
 			//set encoding to be unicode
 			encoding = Encoding.getEncoding("UNICODE", null);
@@ -388,7 +388,7 @@
 			//to make the setting permanent
 			if (acRset.getString(1).equals("off"))
 			{
-				ExecSQL("set autocommit = on; commit;");
+				doQuery("set autocommit = on; commit;");
 			}
 		}
 
@@ -409,14 +409,7 @@
 		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.
 	 * @param msg message to add
@@ -445,66 +438,40 @@
 		//}
 	}
 
-	/*
-	 * 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 doQuery (String s) throws SQLException
 	{
-		return ExecSQL(sql, null);
+		final Object[] nullarr = new Object[0];
+		java.sql.Statement stat = createStatement();
+		java.sql.ResultSet rs = createResultSet(stat);
+		execSQL(new String[] { s }, nullarr, stat, rs);
+		return rs;
 	}
 
-	/*
-	 * Send a query to the backend.  Returns one of the ResultSet
-	 * objects.
+	/** Advanced query execution.
 	 *
-	 * <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
+	 * @param stat the statement associated with this query.
+	 * @param rs the ResultSet which will be initied for 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();
+	public void execSQL(String[] p_sqlFragments,
+			    Object[] p_binds,
+			    java.sql.Statement stat,
+			    java.sql.ResultSet rs)
+		throws SQLException
+	{
+		QueryExecutor.execute(p_sqlFragments,
+				      p_binds,
+				      stat,
+				      rs,
+				      pg_stream,
+				      (java.sql.Connection)this);
 	}
 
+	
 	/*
 	 * In SQL, a result table can be retrieved through a cursor that
 	 * is named.  The current row of a result can be updated or deleted
@@ -939,27 +906,27 @@
                 //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;");
+				doQuery("select 1; commit; set autocommit = on;");
 			}
 			else
 			{
-				ExecSQL("end");				
+				doQuery("end");				
 			}
 		}
 		else
 		{
 			if (haveMinimumServerVersion("7.3"))
 			{
-				ExecSQL("set autocommit = off; " + getIsolationLevelSQL());
+				doQuery("set autocommit = off; " + getIsolationLevelSQL());
 			}
 			else if (haveMinimumServerVersion("7.1"))
 			{
-				ExecSQL("begin;" + getIsolationLevelSQL());
+				doQuery("begin;" + getIsolationLevelSQL());
 			}
 			else
 			{
-				ExecSQL("begin");
-				ExecSQL(getIsolationLevelSQL());
+				doQuery("begin");
+				doQuery(getIsolationLevelSQL());
 			}
 		}
 		this.autoCommit = autoCommit;
@@ -993,17 +960,17 @@
 			return ;
 		if (haveMinimumServerVersion("7.3"))
 		{
-			ExecSQL("commit; " + getIsolationLevelSQL());
+			doQuery("commit; " + getIsolationLevelSQL());
 		}
 		else if (haveMinimumServerVersion("7.1"))
 		{
-			ExecSQL("commit;begin;" + getIsolationLevelSQL());
+			doQuery("commit;begin;" + getIsolationLevelSQL());
 		}
 		else
 		{
-			ExecSQL("commit");
-			ExecSQL("begin");
-			ExecSQL(getIsolationLevelSQL());
+			doQuery("commit");
+			doQuery("begin");
+			doQuery(getIsolationLevelSQL());
 		}
 	}
 
@@ -1024,17 +991,17 @@
 			//we don't automatically start a transaction 
 			//but let the server functionality automatically start
 			//one when the first statement is executed
-			ExecSQL("rollback; " + getIsolationLevelSQL());
+			doQuery("rollback; " + getIsolationLevelSQL());
 		}
 		else if (haveMinimumServerVersion("7.1"))
 		{
-			ExecSQL("rollback; begin;" + getIsolationLevelSQL());
+			doQuery("rollback; begin;" + getIsolationLevelSQL());
 		}
 		else
 		{
-			ExecSQL("rollback");
-			ExecSQL("begin");
-			ExecSQL(getIsolationLevelSQL());
+			doQuery("rollback");
+			doQuery("begin");
+			doQuery(getIsolationLevelSQL());
 		}
 	}
 
@@ -1049,14 +1016,14 @@
 		String sql = "show transaction isolation level";
 		String level = null;
 		if (haveMinimumServerVersion("7.3")) {
-			ResultSet rs = ExecSQL(sql);
+			ResultSet rs = doQuery(sql);
 			if (rs.next()) {
 				level = rs.getString(1);
 			}
 			rs.close();
 		} else {
 			clearWarnings();
-			ExecSQL(sql);
+			doQuery(sql);
 			SQLWarning warning = getWarnings();
 			if (warning != null)
 			{
@@ -1121,7 +1088,7 @@
 											new Integer(isolationLevel));
 			}
 		}
-		ExecSQL(isolationLevelSQL);
+		doQuery(isolationLevelSQL);
 	}
 
 	/*
@@ -1264,7 +1231,7 @@
 				} else {
 					sql = "SELECT typname FROM pg_type WHERE oid = " +oid;
 				}
-				ResultSet result = ExecSQL(sql);
+				ResultSet result = doQuery(sql);
 				if (((AbstractJdbc1ResultSet)result).getColumnCount() != 1 || ((AbstractJdbc1ResultSet)result).getTupleCount() != 1) {
 					throw new PSQLException("postgresql.unexpected");
 				}
@@ -1305,7 +1272,7 @@
 				} else {
 					sql = "SELECT oid FROM pg_type WHERE typname='" + typeName + "'";
 				}
-				ResultSet result = ExecSQL(sql);
+				ResultSet result = doQuery(sql);
 				if (((AbstractJdbc1ResultSet)result).getColumnCount() != 1 || ((AbstractJdbc1ResultSet)result).getTupleCount() != 1)
 					throw new PSQLException("postgresql.unexpected");
 				result.next();
@@ -1413,21 +1380,21 @@
 	 * 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)
Index: org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java,v
retrieving revision 1.10.2.2
diff -u -r1.10.2.2 AbstractJdbc1DatabaseMetaData.java
--- org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java	2002/12/05 01:09:58	1.10.2.2
+++ org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java	2002/12/11 14:13:37
@@ -1913,7 +1913,9 @@
 		}
 		rs.close();
 
-		return connection.getResultSet(null, f, v, "OK", 1);
+		java.sql.ResultSet retRs = connection.createResultSet(connection.createStatement());
+		((AbstractJdbc1ResultSet)retRs).init(f, v, "OK", 1, 0, false);
+		return retRs;
 	}
 
 	/*
@@ -2199,7 +2201,10 @@
 			tuple[0] = types[i].getBytes();
 			v.addElement(tuple);
 		}
-		return connection.getResultSet(null, f, v, "OK", 1);
+
+		java.sql.ResultSet retRs = connection.createResultSet(connection.createStatement());
+		((AbstractJdbc1ResultSet)retRs).init(f, v, "OK", 1, 0, false);
+		return retRs;
 	}
 
 	/*
@@ -2366,7 +2371,9 @@
 		}
 		rs.close();
 
-		return connection.getResultSet(null, f, v, "OK", 1);
+		java.sql.ResultSet retRs = connection.createResultSet(connection.createStatement());
+		((AbstractJdbc1ResultSet)retRs).init(f, v, "OK", 1, 0, false);
+		return retRs;
 	}
 
 	/*
@@ -2478,7 +2485,10 @@
 			}
 		}
 		rs.close();
-		return connection.getResultSet(null, f, v, "OK", 1);
+
+		java.sql.ResultSet retRs = connection.createResultSet(connection.createStatement());
+		((AbstractJdbc1ResultSet)retRs).init(f, v, "OK", 1, 0, false);
+		return retRs;
 	}
 
 	/*
@@ -2580,7 +2590,9 @@
 		}
 		rs.close();
 
-		return connection.getResultSet(null, f, v, "OK", 1);
+		java.sql.ResultSet retRs = connection.createResultSet(connection.createStatement());
+		((AbstractJdbc1ResultSet)retRs).init(f, v, "OK", 1, 0, false);
+		return retRs;
 	}
 
 	private static void sortStringArray(String s[]) {
@@ -2773,7 +2785,10 @@
 			tuple[7] = Integer.toString(java.sql.DatabaseMetaData.bestRowNotPseudo).getBytes();
 			v.addElement(tuple);
 		}
-		return connection.getResultSet(null, f, v, "OK", 1);
+
+		java.sql.ResultSet retRs = connection.createResultSet(connection.createStatement());
+		((AbstractJdbc1ResultSet)retRs).init(f, v, "OK", 1, 0, false);
+		return retRs;
 	}
 
 	/*
@@ -2843,7 +2858,9 @@
 		/* Perhaps we should check that the given
 		 * catalog.schema.table actually exists. -KJ
 		 */
-		return connection.getResultSet(null, f, v, "OK", 1);
+		java.sql.ResultSet retRs = connection.createResultSet(connection.createStatement());
+		((AbstractJdbc1ResultSet)retRs).init(f, v, "OK", 1, 0, false);
+		return retRs;
 	}
 
 	/*
@@ -3193,7 +3210,9 @@
 			tuples.addElement(tuple);
 		}
 
-		return connection.getResultSet(null, f, tuples, "OK", 1);
+		java.sql.ResultSet retRs = connection.createResultSet(connection.createStatement());
+		((AbstractJdbc1ResultSet)retRs).init(f, tuples, "OK", 1, 0, false);
+		return retRs;
 	}
 
 	/*
@@ -3478,7 +3497,10 @@
 			v.addElement(tuple);
 		}
 		rs.close();
-		return connection.getResultSet(null, f, v, "OK", 1);
+
+		java.sql.ResultSet retRs = connection.createResultSet(connection.createStatement());
+		((AbstractJdbc1ResultSet)retRs).init(f, v, "OK", 1, 0, false);
+		return retRs;
 	}
 
 	/*
Index: org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java,v
retrieving revision 1.7
diff -u -r1.7 AbstractJdbc1ResultSet.java
--- org/postgresql/jdbc1/AbstractJdbc1ResultSet.java	2002/10/19 22:10:36	1.7
+++ org/postgresql/jdbc1/AbstractJdbc1ResultSet.java	2002/12/11 14:13:38
@@ -18,7 +18,7 @@
  * 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 implements org.postgresql.PGResultSet
 {
 
 	protected Vector rows;			// The results
@@ -42,7 +42,13 @@
 	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(org.postgresql.PGConnection conn,
+				      Statement statement,
+				      Field[] fields,
+				      Vector tuples,
+				      String status,
+				      int updateCount,
+				      long insertOID, boolean binaryCursor)
 	{
 		this.connection = conn;
 		this.statement = statement;
@@ -50,20 +56,72 @@
 		this.rows = tuples;
 		this.status = status;
 		this.updateCount = updateCount;
+
+		System.out.println(getClass().getName() + " updateCount = " + updateCount);
+		
+		this.insertOID = insertOID;
+		this.this_row = null;
+		this.current_row = -1;
+		this.binaryCursor = binaryCursor;
+	}
+
+
+	/*** nic constructor: called by superclass which is called from Jdbc1Connection.createResultSet ***/
+	public AbstractJdbc1ResultSet(org.postgresql.PGConnection conn,
+				      Statement statement)
+	{
+		this.connection = conn;
+		this.statement = statement;
+	}
+	
+	/*** nic initializer. ***/
+	public void init (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;
 	}
+  
 
 
+
+	// This slightly altered by nic.
 	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 + " ;";
+			((AbstractJdbc1Connection)connection).execSQL(sql, binds, statement, (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);
 
@@ -501,6 +559,13 @@
 				if (type.equals("unknown"))
 				{
 					return getString(columnIndex);
+				}
+				else if (type.equals("refcursor"))
+				{
+					// We must return a ResultSet with the results packaged.
+				        // We should probably check that auto commit is turned off.
+				        String cursorName = getString(columnIndex);
+					return connection.createRefCursorResultSet(statement, cursorName);
 				}
 				else
 				{
Index: org/postgresql/jdbc1/AbstractJdbc1Statement.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java,v
retrieving revision 1.12.2.2
diff -u -r1.12.2.2 AbstractJdbc1Statement.java
--- org/postgresql/jdbc1/AbstractJdbc1Statement.java	2002/11/20 07:54:27	1.12.2.2
+++ org/postgresql/jdbc1/AbstractJdbc1Statement.java	2002/12/11 14:13:40
@@ -25,6 +25,9 @@
 	/** 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 +50,10 @@
 	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;
 
@@ -117,7 +122,7 @@
 
 	}
 
-
+  
 	/*
 	 * Execute a SQL statement that retruns a single ResultSet
 	 *
@@ -132,11 +137,21 @@
 		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).doQuery("DEALLOCATE " + m_statementName);
+			}
+			catch (Exception e)
+			{
+			}
+			finally
+			{
+				m_statementName = null;
+				m_origSqlFragments = null;
+				m_executeSqlFragments = null;
+			}
 		}
 		return executeQuery();
 	}
@@ -150,7 +165,11 @@
 	 */
 	public java.sql.ResultSet executeQuery() throws SQLException
 	{
-		this.execute();
+		if (fetchSize > 0)
+			this.nic_execute();
+		else
+			this.execute();
+	
 		while (result != null && !((AbstractJdbc1ResultSet)result).reallyResultSet())
 			result = ((AbstractJdbc1ResultSet)result).getNext();
 		if (result == null)
@@ -175,7 +194,7 @@
 		//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).doQuery("DEALLOCATE " + m_statementName);
 			m_statementName = null;
 			m_origSqlFragments = null;
 			m_executeSqlFragments = null;
@@ -219,7 +238,7 @@
 		//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).doQuery("DEALLOCATE " + m_statementName);
 			m_statementName = null;
 			m_origSqlFragments = null;
 			m_executeSqlFragments = null;
@@ -317,7 +336,9 @@
 		}
 
 		// 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 = ((AbstractJdbc1Connection)connection).createResultSet((java.sql.Statement)this);
+		((AbstractJdbc1Connection)connection).execSQL(m_sqlFragments, m_binds,
+							      (java.sql.Statement)this, result);
 
 		//If we are executing a callable statement function set the return data
 		if (isFunction)
@@ -341,6 +362,104 @@
 		}
 	}
 
+	/** version of execute which converts the query to a cursor.
+	 */
+	public boolean nic_execute() 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);
+		}
+
+		// Make the call to the query executor.
+		AbstractJdbc1Connection execr = (AbstractJdbc1Connection)connection;
+		java.sql.Statement st = (java.sql.Statement)this;
+		result = (java.sql.ResultSet) execr.createResultSet(st);
+		execr.execSQL(m_sqlFragments, m_binds, st, result);
+
+		//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 +712,7 @@
 
 		// If using server prepared statements deallocate them
 		if (m_useServerPrepare && m_statementName != null) {
-			((AbstractJdbc1Connection)connection).ExecSQL("DEALLOCATE " + m_statementName);
+			((AbstractJdbc1Connection)connection).doQuery("DEALLOCATE " + m_statementName);
 		}
 
 		// Disasociate it from us (For Garbage Collection)
@@ -1690,7 +1809,7 @@
 	 */
 	public byte[] getBytes(int parameterIndex) throws SQLException
 	{
-		checkIndex (parameterIndex, Types.VARBINARY, "Bytes");
+		checkIndex (parameterIndex, Types.VARBINARY, Types.BINARY, "Bytes");
 		return ((byte [])callResult);
 	}
 
@@ -1797,6 +1916,10 @@
 	 */
 	protected void bind(int paramIndex, Object s, String type) throws SQLException
 	{
+		// System.out.println("AbstractJdbc1Statement bind("
+		// 	   + paramIndex + ", "
+		// 	   + s + ", "
+		// 	   + type + ") + m_binds.length = " + m_binds.length);
 		if (paramIndex < 1 || paramIndex > m_binds.length)
 			throw new PSQLException("postgresql.prep.range");
 		if (paramIndex == 1 && isFunction) // need to registerOut instead
@@ -1847,7 +1970,7 @@
 		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,23 +1998,37 @@
 		// 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
 	{
 		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 +2049,7 @@
 			//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).doQuery("DEALLOCATE " + m_statementName);
 			m_statementName = null;
 			m_useServerPrepare = flag;
 		} else {
Index: org/postgresql/jdbc1/Jdbc1Connection.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java,v
retrieving revision 1.5
diff -u -r1.5 Jdbc1Connection.java
--- org/postgresql/jdbc1/Jdbc1Connection.java	2002/09/06 21:23:06	1.5
+++ org/postgresql/jdbc1/Jdbc1Connection.java	2002/12/11 14:13:40
@@ -36,16 +36,20 @@
 		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
+
+
+	// Methods for creating result sets
+
+	public java.sql.ResultSet createResultSet (java.sql.Statement stat) throws SQLException
 	{
-		return new Jdbc1ResultSet(this, stat, fields, tuples, status, updateCount, insertOID, binaryCursor);
+		// This needs doing.
+		return null;
 	}
 
-	public java.sql.ResultSet getResultSet(java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException
+	public PGRefCursorResultSet createRefCursorResultSet (java.sql.Statement stat, String cursorHandle) throws SQLException
 	{
-		return new Jdbc1ResultSet(this, stat, fields, tuples, status, updateCount, 0, false);
+		return new Jdbc1RefCursorResultSet(stat, cursorHandle);
 	}
-
 }
 
 
Index: org/postgresql/jdbc1/Jdbc1RefCursorResultSet.java
===================================================================
RCS file: Jdbc1RefCursorResultSet.java
diff -N Jdbc1RefCursorResultSet.java
--- /dev/null	Wed Dec 11 09:09:00 2002
+++ Jdbc1RefCursorResultSet.java	Wed Dec 11 09:13:41 2002
@@ -0,0 +1,40 @@
+package org.postgresql.jdbc1;
+
+
+
+/** A real result set based on a ref cursor.
+ *
+ * @author Nic Ferrier <nferrier@tapsellferrier.co.uk>
+ */
+public class Jdbc1RefCursorResultSet extends AbstractJdbc1ResultSet implements PGRefCursorResultSet
+{
+
+	java.sql.Statement statement;
+	String refCursorHandle;
+
+	// Indicates when the result set has activaly bound to the cursor.
+	boolean isInitialized = false;
+
+	Jdbc1RefCursorResultSet(java.sql.Statement statement, String refCursorName)
+	{
+		this.statement = statement;
+		this.refCursorHandle = refCursorName;
+	}
+
+	public String getRefCursor ()
+	{
+		return refCursorHandle;
+	}
+
+	public boolean next () throws SQLException
+	{
+		if (isInitialized)
+			return super.next();
+		// Initialize this res set with the rows from the cursor.
+		String[] toExec = { "FETCH ALL IN \"" + refCursorHandle + "\";" };
+		Jdbc1Connection execr = (Jdbc1Connection) statement.getConnection();
+		execr.execSQL(toExec, new String[0], statement, this);
+		isInitialized = true;
+		return super.next();
+	}
+}
Index: org/postgresql/jdbc1/Jdbc1Statement.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java,v
retrieving revision 1.3
diff -u -r1.3 Jdbc1Statement.java
--- org/postgresql/jdbc1/Jdbc1Statement.java	2002/09/06 21:23:06	1.3
+++ org/postgresql/jdbc1/Jdbc1Statement.java	2002/12/11 14:13:41
@@ -16,4 +16,5 @@
 		super(c);
 	}
 
+  
 }
Index: org/postgresql/jdbc2/AbstractJdbc2Connection.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v
retrieving revision 1.2
diff -u -r1.2 AbstractJdbc2Connection.java
--- org/postgresql/jdbc2/AbstractJdbc2Connection.java	2002/09/06 21:23:06	1.2
+++ org/postgresql/jdbc2/AbstractJdbc2Connection.java	2002/12/11 14:13:41
@@ -6,6 +6,7 @@
 import java.sql.*;
 import org.postgresql.util.PSQLException;
 
+
 /* $Header: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v 1.2 2002/09/06 21:23:06 momjian Exp $
  * This class defines methods of the jdbc2 specification.  This class extends
  * org.postgresql.jdbc1.AbstractJdbc1Connection which provides the jdbc1
@@ -17,7 +18,7 @@
 	 * 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
Index: org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java,v
retrieving revision 1.10
diff -u -r1.10 AbstractJdbc2ResultSet.java
--- org/postgresql/jdbc2/AbstractJdbc2ResultSet.java	2002/11/04 06:42:33	1.10
+++ org/postgresql/jdbc2/AbstractJdbc2ResultSet.java	2002/12/11 14:13:42
@@ -38,6 +38,11 @@
 	protected PreparedStatement deleteStatement = null;
 	private PreparedStatement selectStatement = null;
 
+  
+	protected AbstractJdbc2ResultSet (org.postgresql.PGConnection conn, Statement statement)
+	{
+		super(conn, statement);
+	}
 
 
 	public AbstractJdbc2ResultSet(org.postgresql.PGConnection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
@@ -142,6 +147,13 @@
 				{
 					return getString(columnIndex);
 				}
+				else if (type.equals("refcursor"))
+				{
+					// We must return a ResultSet with the results packaged.
+				        // We should probably check that auto commit is turned off.
+				        String cursorName = getString(columnIndex);
+					return connection.createRefCursorResultSet(statement, cursorName);
+				}
 				else
 				{
 					return connection.getObject(field.getPGType(), getString(columnIndex));
@@ -366,9 +378,7 @@
 
 	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 +764,6 @@
 		}
 
 		updateValue(columnIndex, theData);
-
 	}
 
 
@@ -787,7 +796,6 @@
 			throw new PSQLException("postgresql.updateable.ioerror" + ie);
 		}
 		updateValue(columnIndex, theData);
-
 	}
 
 
Index: org/postgresql/jdbc2/AbstractJdbc2Statement.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java,v
retrieving revision 1.8.2.2
diff -u -r1.8.2.2 AbstractJdbc2Statement.java
--- org/postgresql/jdbc2/AbstractJdbc2Statement.java	2002/11/20 20:42:24	1.8.2.2
+++ org/postgresql/jdbc2/AbstractJdbc2Statement.java	2002/12/11 14:13:42
@@ -133,7 +133,7 @@
 
 	public int getFetchSize() throws SQLException
 	{
-		return 0;
+		return super.fetchSize;
 	}
 
 	public int getResultSetConcurrency() throws SQLException
@@ -148,12 +148,16 @@
 
 	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();
+		// if (super.fetchSize > 0 && rows == 0)
+                //     throw new SQLException("you can't set fetch size to 0 during ");
+		super.fetchSize = rows;
 	}
 
 	public void setResultSetConcurrency(int value) throws SQLException
Index: org/postgresql/jdbc2/Array.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java,v
retrieving revision 1.18
diff -u -r1.18 Array.java
--- org/postgresql/jdbc2/Array.java	2002/09/06 21:23:06	1.18
+++ org/postgresql/jdbc2/Array.java	2002/12/11 14:13:43
@@ -343,7 +343,10 @@
 			default:
 				throw org.postgresql.Driver.notImplemented();
 		}
-		return ((AbstractJdbc2Connection)conn).getResultSet(null, fields, rows, "OK", 1 );
+		java.sql.Statement stat = ((AbstractJdbc2Connection)conn).createStatement();
+		java.sql.ResultSet retRs = ((AbstractJdbc2Connection)conn).createResultSet(stat);
+		((AbstractJdbc2ResultSet)retRs).init(fields, rows, "OK", 1, 0, false);
+		return retRs;
 	}
 
 	public String toString()
Index: org/postgresql/jdbc2/Jdbc2Connection.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java,v
retrieving revision 1.5
diff -u -r1.5 Jdbc2Connection.java
--- org/postgresql/jdbc2/Jdbc2Connection.java	2002/09/06 21:23:06	1.5
+++ org/postgresql/jdbc2/Jdbc2Connection.java	2002/12/11 14:13:43
@@ -6,6 +6,7 @@
 import java.util.Hashtable;
 import org.postgresql.Field;
 
+
 /* $Header: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java,v 1.5 2002/09/06 21:23:06 momjian Exp $
  * This class implements the java.sql.Connection interface for JDBC2.
  * However most of the implementation is really done in
@@ -45,17 +46,21 @@
 			metadata = new org.postgresql.jdbc2.Jdbc2DatabaseMetaData(this);
 		return metadata;
 	}
+
+  
 
-	public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
+	// Result set creation.
+
+	/** new nic method **/
+	public java.sql.ResultSet createResultSet (Statement statement)
 	{
-		return new Jdbc2ResultSet(this, statement, fields, tuples, status, updateCount, insertOID, binaryCursor);
+		return new Jdbc2ResultSet(this, statement);
 	}
 
-	public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException
+  	public org.postgresql.PGRefCursorResultSet createRefCursorResultSet (java.sql.Statement stat, String cursorHandle) throws SQLException
 	{
-		return new Jdbc2ResultSet(this, statement, fields, tuples, status, updateCount, 0, false);
+		return new Jdbc2RefCursorResultSet(stat, cursorHandle);
 	}
-
 
 }
 
Index: org/postgresql/jdbc2/Jdbc2RefCursorResultSet.java
===================================================================
RCS file: Jdbc2RefCursorResultSet.java
diff -N Jdbc2RefCursorResultSet.java
--- /dev/null	Wed Dec 11 09:09:00 2002
+++ Jdbc2RefCursorResultSet.java	Wed Dec 11 09:13:43 2002
@@ -0,0 +1,41 @@
+package org.postgresql.jdbc2;
+
+
+import org.postgresql.PGConnection;
+
+
+/** A real result set based on a ref cursor.
+ *
+ * @author Nic Ferrier <nferrier@tapsellferrier.co.uk>
+ */
+public class Jdbc2RefCursorResultSet extends Jdbc2ResultSet implements org.postgresql.PGRefCursorResultSet
+{
+
+	String refCursorHandle;
+
+	// Indicates when the result set has activaly bound to the cursor.
+	boolean isInitialized = false;
+
+	Jdbc2RefCursorResultSet(java.sql.Statement statement, String refCursorName) throws java.sql.SQLException
+	{
+		super((PGConnection)statement.getConnection(), statement);
+		this.refCursorHandle = refCursorName;
+	}
+
+	public String getRefCursor ()
+	{
+		return refCursorHandle;
+	}
+
+	public boolean next () throws java.sql.SQLException
+	{
+		if (isInitialized)
+			return super.next();
+		// Initialize this res set with the rows from the cursor.
+		String[] toExec = { "FETCH ALL IN \"" + refCursorHandle + "\";" };
+		Jdbc2Connection execr = (Jdbc2Connection) statement.getConnection();
+		execr.execSQL(toExec, new String[0], statement, this);
+		isInitialized = true;
+		return super.next();
+	}
+}
Index: org/postgresql/jdbc2/Jdbc2ResultSet.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2ResultSet.java,v
retrieving revision 1.6
diff -u -r1.6 Jdbc2ResultSet.java
--- org/postgresql/jdbc2/Jdbc2ResultSet.java	2002/09/11 05:38:45	1.6
+++ org/postgresql/jdbc2/Jdbc2ResultSet.java	2002/12/11 14:13:43
@@ -13,6 +13,12 @@
 public class Jdbc2ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet implements java.sql.ResultSet
 {
 
+	Jdbc2ResultSet (org.postgresql.PGConnection conn, Statement statement)
+	{
+		super (conn, statement);
+	}
+  
+
 	public Jdbc2ResultSet(Jdbc2Connection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
 	{
 		super(conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor);
Index: org/postgresql/jdbc3/AbstractJdbc3ResultSet.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3ResultSet.java,v
retrieving revision 1.2
diff -u -r1.2 AbstractJdbc3ResultSet.java
--- org/postgresql/jdbc3/AbstractJdbc3ResultSet.java	2002/09/06 21:23:06	1.2
+++ org/postgresql/jdbc3/AbstractJdbc3ResultSet.java	2002/12/11 14:13:43
@@ -12,6 +12,12 @@
 public abstract class AbstractJdbc3ResultSet extends org.postgresql.jdbc2.AbstractJdbc2ResultSet
 {
 
+	protected AbstractJdbc3ResultSet (org.postgresql.PGConnection conn, Statement statement)
+	{
+		super(conn, statement);
+	}
+
+  
 	public AbstractJdbc3ResultSet(org.postgresql.PGConnection conn, 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);
Index: org/postgresql/jdbc3/Jdbc3Connection.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3Connection.java,v
retrieving revision 1.2
diff -u -r1.2 Jdbc3Connection.java
--- org/postgresql/jdbc3/Jdbc3Connection.java	2002/09/06 21:23:06	1.2
+++ org/postgresql/jdbc3/Jdbc3Connection.java	2002/12/11 14:13:43
@@ -46,16 +46,18 @@
 		return metadata;
 	}
 
-	public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException
+
+  
+	/** new nic method **/
+	public java.sql.ResultSet createResultSet (Statement statement)
 	{
-		return new Jdbc3ResultSet(this, statement, fields, tuples, status, updateCount, insertOID, binaryCursor);
+		return new Jdbc3ResultSet(this, statement);
 	}
+
 
-	public java.sql.ResultSet getResultSet(Statement statement, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException
+	public org.postgresql.PGRefCursorResultSet createRefCursorResultSet (java.sql.Statement statement, String cursorName) throws SQLException
 	{
-		return new Jdbc3ResultSet(this, statement, fields, tuples, status, updateCount, 0, false);
+		return new Jdbc3RefCursorResultSet(statement, cursorName);
 	}
-
+    
 }
-
-
Index: org/postgresql/jdbc3/Jdbc3RefCursorResultSet.java
===================================================================
RCS file: Jdbc3RefCursorResultSet.java
diff -N Jdbc3RefCursorResultSet.java
--- /dev/null	Wed Dec 11 09:09:00 2002
+++ Jdbc3RefCursorResultSet.java	Wed Dec 11 09:13:43 2002
@@ -0,0 +1,41 @@
+package org.postgresql.jdbc3;
+
+
+import org.postgresql.PGConnection;
+
+
+/** A real result set based on a ref cursor.
+ *
+ * @author Nic Ferrier <nferrier@tapsellferrier.co.uk>
+ */
+public class Jdbc3RefCursorResultSet extends Jdbc3ResultSet implements org.postgresql.PGRefCursorResultSet
+{
+
+	String refCursorHandle;
+
+	// Indicates when the result set has activaly bound to the cursor.
+	boolean isInitialized = false;
+
+	Jdbc3RefCursorResultSet(java.sql.Statement statement, String refCursorName) throws java.sql.SQLException
+	{
+		super((PGConnection)statement.getConnection(), statement);
+		this.refCursorHandle = refCursorName;
+	}
+
+	public String getRefCursor ()
+	{
+		return refCursorHandle;
+	}
+
+	public boolean next () throws java.sql.SQLException
+	{
+		if (isInitialized)
+			return super.next();
+		// Initialize this res set with the rows from the cursor.
+		String[] toExec = { "FETCH ALL IN \"" + refCursorHandle + "\";" };
+		Jdbc3Connection execr = (Jdbc3Connection) statement.getConnection();
+		execr.execSQL(toExec, new String[0], statement, this);
+		isInitialized = true;
+		return super.next();
+	}
+}
Index: org/postgresql/jdbc3/Jdbc3ResultSet.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc3/Jdbc3ResultSet.java,v
retrieving revision 1.3
diff -u -r1.3 Jdbc3ResultSet.java
--- org/postgresql/jdbc3/Jdbc3ResultSet.java	2002/09/11 05:38:45	1.3
+++ org/postgresql/jdbc3/Jdbc3ResultSet.java	2002/12/11 14:13:43
@@ -13,6 +13,13 @@
 public class Jdbc3ResultSet extends org.postgresql.jdbc3.AbstractJdbc3ResultSet implements java.sql.ResultSet
 {
 
+	Jdbc3ResultSet (org.postgresql.PGConnection conn, Statement statement)
+	{
+		super (conn, statement);
+	}
+
+
+  
 	public Jdbc3ResultSet(Jdbc3Connection conn, Statement statement, Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor)
 	{
 		super(conn, statement, fields, tuples, status, updateCount, insertOID, binaryCursor);
Index: org/postgresql/util/Serialize.java
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/util/Serialize.java,v
retrieving revision 1.14
diff -u -r1.14 Serialize.java
--- org/postgresql/util/Serialize.java	2002/10/01 00:39:02	1.14
+++ org/postgresql/util/Serialize.java	2002/12/11 14:13:44
@@ -405,7 +405,7 @@
 
 			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).doQuery(sb.toString());
 
 			// fetch the OID for returning
 			if (update)
