diff --git a/src/interfaces/jdbc/org/postgresql/Connection.java b/src/interfaces/jdbc/org/postgresql/Connection.java
index fc908a43e9ef0f1718b1e74e451840625602e6af..198a7962a185932f92b3e5e968a8a8e10559ecdb 100644
--- a/src/interfaces/jdbc/org/postgresql/Connection.java
+++ b/src/interfaces/jdbc/org/postgresql/Connection.java
@@ -10,7 +10,7 @@ import org.postgresql.largeobject.*;
 import org.postgresql.util.*;
 
 /**
- * $Id: Connection.java,v 1.6 2000/09/12 05:09:54 momjian Exp $
+ * $Id: Connection.java,v 1.7 2000/10/08 19:37:54 momjian Exp $
  *
  * This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
  * JDBC2 versions of the Connection class.
@@ -81,6 +81,11 @@ public abstract class Connection
     // The PID an cancellation key we get from the backend process
     public int pid;
     public int ckey;
+
+    // This receive_sbuf should be used by the different methods
+    // that call pg_stream.ReceiveString() in this Connection, so 
+    // so we avoid uneccesary new allocations. 
+    byte receive_sbuf[] = new byte[8192];
     
     /**
      * This is called by Class.forName() from within org.postgresql.Driver
@@ -164,8 +169,9 @@ public abstract class Connection
 		// The most common one to be thrown here is:
 		// "User authentication failed"
 		//
-		throw new SQLException(pg_stream.ReceiveString
-                                       (4096, getEncoding()));
+		String msg = pg_stream.ReceiveString(receive_sbuf, 4096,
+						     getEncoding());
+		throw new SQLException(msg);
 		
 	      case 'R':
 		// Get the type of request
@@ -236,7 +242,7 @@ public abstract class Connection
 	case 'E':
 	case 'N':
            throw new SQLException(pg_stream.ReceiveString
-                                  (4096, getEncoding()));
+                                  (receive_sbuf, 4096, getEncoding()));
         default:
           throw new PSQLException("postgresql.con.setup");
       }
@@ -248,7 +254,7 @@ public abstract class Connection
 	   break;
 	case 'E':
 	case 'N':
-           throw new SQLException(pg_stream.ReceiveString(4096));
+           throw new SQLException(pg_stream.ReceiveString(receive_sbuf, 4096, getEncoding()));
         default:
           throw new PSQLException("postgresql.con.setup");
       }
@@ -263,7 +269,7 @@ public abstract class Connection
       //
       firstWarning = null;
       
-      ExecSQL("set datestyle to 'ISO'");
+      ExecSQL(null, "set datestyle to 'ISO'");
       
       // Initialise object handling
       initObjectTypes();
@@ -306,7 +312,8 @@ public abstract class Connection
 	//currentDateStyle=i+1; // this is the index of the format
 	//}
     }
-    
+
+
     /**
      * Send a query to the backend.  Returns one of the ResultSet
      * objects.
@@ -314,15 +321,18 @@ public abstract class Connection
      * <B>Note:</B> there does not seem to be any method currently
      * in existance to return the update count.
      *
+     * @param stmt The statment object.
      * @param sql the SQL statement to be executed
      * @return a ResultSet holding the results
      * @exception SQLException if a database error occurs
      */
-    public java.sql.ResultSet ExecSQL(String sql) throws SQLException
+    public java.sql.ResultSet ExecSQL(PGStatement stmt, 
+				      String sql) throws SQLException
     {
 	// added Oct 7 1998 to give us thread safety.
 	synchronized(pg_stream) {
-	    
+	    pg_stream.setExecutingStatement(stmt);
+
 	    Field[] fields = null;
 	    Vector tuples = new Vector();
 	    byte[] buf = null;
@@ -352,8 +362,7 @@ public abstract class Connection
 	    try
 		{
 		    pg_stream.SendChar('Q');
-		    buf = sql.getBytes();
-		    pg_stream.Send(buf);
+		    pg_stream.Send(sql.getBytes());
 		    pg_stream.SendChar(0);
 		    pg_stream.flush();
 		} catch (IOException e) {
@@ -370,7 +379,8 @@ public abstract class Connection
 			{
 			case 'A':	// Asynchronous Notify
 			    pid = pg_stream.ReceiveInteger(4);
-			    msg = pg_stream.ReceiveString(8192);
+			    msg = pg_stream.ReceiveString(receive_sbuf, 8192, 
+							  getEncoding());
 			    break;
 			case 'B':	// Binary Data Transfer
 			    if (fields == null)
@@ -381,7 +391,9 @@ public abstract class Connection
 				tuples.addElement(tup);
 			    break;
 			case 'C':	// Command Status
-			    recv_status = pg_stream.ReceiveString(8192);
+			    recv_status = 
+				pg_stream.ReceiveString(receive_sbuf, 8192,
+							getEncoding());
 				
 				// Now handle the update count correctly.
 				if(recv_status.startsWith("INSERT") || recv_status.startsWith("UPDATE") || recv_status.startsWith("DELETE")) {
@@ -423,7 +435,8 @@ public abstract class Connection
 				tuples.addElement(tup);
 			    break;
 			case 'E':	// Error Message
-			    msg = pg_stream.ReceiveString(4096);
+			    msg = pg_stream.ReceiveString(receive_sbuf, 4096,
+							  getEncoding());
 			    final_error = new SQLException(msg);
 			    hfr = true;
 			    break;
@@ -438,10 +451,14 @@ public abstract class Connection
 				hfr = true;
 			    break;
 			case 'N':	// Error Notification
-			    addWarning(pg_stream.ReceiveString(4096));
+			    addWarning(pg_stream.ReceiveString(receive_sbuf, 
+							       4096, 
+							       getEncoding()));
 			    break;
 			case 'P':	// Portal Name
-			    String pname = pg_stream.ReceiveString(8192);
+			    String pname = 
+				pg_stream.ReceiveString(receive_sbuf, 8192, 
+							getEncoding());
 			    break;
 			case 'T':	// MetaData Field Description
 			    if (fields != null)
@@ -461,6 +478,8 @@ public abstract class Connection
 	}
     }
 
+
+
     /**
      * Receive the field descriptions from the back end
      *
@@ -474,7 +493,8 @@ public abstract class Connection
 	
 	for (i = 0 ; i < nf ; ++i)
 	    {
-		String typname = pg_stream.ReceiveString(8192);
+		String typname = pg_stream.ReceiveString(receive_sbuf, 8192,
+							 getEncoding());
 		int typid = pg_stream.ReceiveIntegerR(4);
 		int typlen = pg_stream.ReceiveIntegerR(2);
 		int typmod = pg_stream.ReceiveIntegerR(4);
diff --git a/src/interfaces/jdbc/org/postgresql/Field.java b/src/interfaces/jdbc/org/postgresql/Field.java
index b73c224e51faa080a242b3a01204d578dff3c371..6e3edab1be7fc4463091ca29d2b47ca7d46c79a4 100644
--- a/src/interfaces/jdbc/org/postgresql/Field.java
+++ b/src/interfaces/jdbc/org/postgresql/Field.java
@@ -76,7 +76,9 @@ public class Field
       // it's not in the cache, so perform a query, and add the result to
       // the cache
       if(type_name==null) {
-	ResultSet result = (org.postgresql.ResultSet)conn.ExecSQL("select typname from pg_type where oid = " + oid);
+	ResultSet result = (org.postgresql.ResultSet)
+	    conn.ExecSQL(null, "select typname from pg_type where oid = " 
+			 + oid);
 	if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
 	  throw new PSQLException("postgresql.unexpected");
 	result.next();
diff --git a/src/interfaces/jdbc/org/postgresql/ObjectPool.java b/src/interfaces/jdbc/org/postgresql/ObjectPool.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ab4506c21bdd01f66092194c527de9f52d1213b
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/ObjectPool.java
@@ -0,0 +1,86 @@
+package org.postgresql;
+
+/**
+ * A simple and fast object pool implementation that can pool objects 
+ * of any type. This implementation is not thread safe, it is up to the users
+ * of this class to assure thread safety. 
+ */
+public class ObjectPool {
+    int cursize = 0;
+    int maxsize = 8;
+    Object arr[] = new Object[8];
+    
+    /**
+     * Add object to the pool.
+     * @param o The object to add.
+     */
+    public void add(Object o){
+	if(cursize >= maxsize){
+	    Object newarr[] = new Object[maxsize*2];
+	    System.arraycopy(arr, 0, newarr, 0, maxsize);
+	    maxsize = maxsize * 2;
+	    arr = newarr;
+	}
+	arr[cursize++] = o;
+    }
+    
+    /**
+     * Remove an object from the pool. If the pool is empty
+     * ArrayIndexOutOfBoundsException will be thrown.
+     * @return Returns the removed object.
+     * @exception If the pool is empty 
+     *            ArrayIndexOutOfBoundsException will be thrown.
+     */
+    public Object remove(){
+	Object o = arr[cursize-1];
+	// This have to be here, so we don't decrease the counter when
+	// cursize == 0;
+	cursize--;
+	return o;
+    }
+
+    /**
+     * Check if pool is empty.
+     * @return true if pool is empty, false otherwise.
+     */
+    public boolean isEmpty(){
+	return cursize == 0;
+    }
+    
+    /**
+     * Get the size of the pool.
+     * @return Returns the number of objects in the pool.
+     */
+    public int size(){
+	return cursize;
+    }
+    /**
+     * Add all the objects from another pool to this pool.
+     * @pool The pool to add the objects from.
+     */
+    public void addAll(ObjectPool pool){
+	int srcsize = pool.size();
+	if(srcsize == 0)
+	    return;
+	int totalsize = srcsize + cursize;
+	if(totalsize > maxsize){
+	    Object newarr[] = new Object[totalsize*2];
+	    System.arraycopy(arr, 0, newarr, 0, cursize);
+	    maxsize = maxsize = totalsize * 2;
+	    arr = newarr;
+	}
+	System.arraycopy(pool.arr, 0, arr, cursize, srcsize);
+	cursize = totalsize;
+    }
+
+    /**
+     * Clear the elements from this pool.
+     * The method is lazy, so it just resets the index counter without
+     * removing references to pooled objects. This could possibly 
+     * be an issue with garbage collection, depending on how the 
+     * pool is used.
+     */
+    public void clear(){
+	cursize = 0;
+    }
+}
diff --git a/src/interfaces/jdbc/org/postgresql/ObjectPoolFactory.java b/src/interfaces/jdbc/org/postgresql/ObjectPoolFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..404c366daa6cc04cb5e7cee3f4a9fc2a84af2563
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/ObjectPoolFactory.java
@@ -0,0 +1,57 @@
+package org.postgresql;
+
+import java.util.Hashtable;
+
+/**
+ * Just a factory class for creating and reusing 
+ * ObjectPool arrays of different sizes.
+ */
+public class ObjectPoolFactory {
+    private static Hashtable instances = new Hashtable();
+
+    ObjectPool pool = new ObjectPool();
+    int maxsize;
+
+    public static ObjectPoolFactory getInstance(int size){
+	Integer s = new Integer(size);
+	ObjectPoolFactory poolFactory = (ObjectPoolFactory) instances.get(s);
+	if(poolFactory == null){
+	    synchronized(instances) {
+		poolFactory = (ObjectPoolFactory) instances.get(s);
+		if(poolFactory == null){
+		    poolFactory = new ObjectPoolFactory(size);
+		    instances.put(s, poolFactory);
+		}
+	    }
+	}
+	return poolFactory;
+    }
+
+    private ObjectPoolFactory(int maxsize){
+	this.maxsize = maxsize;
+    }
+    
+    public ObjectPool[] getObjectPoolArr(){
+	ObjectPool p[] = null;
+	synchronized(pool){
+	    if(pool.size() > 0)
+		p = (ObjectPool []) pool.remove();
+	}
+	if(p == null) {
+	    p = new ObjectPool[maxsize];
+	    for(int i = 0; i < maxsize; i++){
+		p[i] = new ObjectPool();
+	    }
+	}
+	return p;
+    }
+
+    public void releaseObjectPoolArr(ObjectPool p[]){
+	synchronized(pool){
+	    pool.add(p);
+	    for(int i = 0; i < maxsize; i++){
+		p[i].clear();
+	    }
+	}
+    }
+}
diff --git a/src/interfaces/jdbc/org/postgresql/PGStatement.java b/src/interfaces/jdbc/org/postgresql/PGStatement.java
new file mode 100644
index 0000000000000000000000000000000000000000..85fd5a5b85e20bec92cbd0d9839ede7b9a4f531c
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/PGStatement.java
@@ -0,0 +1,26 @@
+package org.postgresql;
+
+import java.sql.Statement;
+import java.sql.SQLException;
+
+public abstract class PGStatement implements Statement {
+    public ObjectPool inusemap_dim1[];
+    public ObjectPool inusemap_dim2[];
+    protected Connection connection;
+
+    public PGStatement(Connection connection){
+	this.connection = connection;
+	inusemap_dim1 = connection.pg_stream.factory_dim1.getObjectPoolArr();
+	inusemap_dim2 = connection.pg_stream.factory_dim2.getObjectPoolArr();
+    }
+ 
+    public void deallocate(){
+	connection.pg_stream.deallocate(this);
+    }
+
+    public void close() throws SQLException {
+	deallocate();
+	connection.pg_stream.factory_dim1.releaseObjectPoolArr(inusemap_dim1);
+	connection.pg_stream.factory_dim2.releaseObjectPoolArr(inusemap_dim2);
+    }
+}
diff --git a/src/interfaces/jdbc/org/postgresql/PG_Stream.java b/src/interfaces/jdbc/org/postgresql/PG_Stream.java
index 22c41bdb3a3ab3de14742117d612770270fc5c08..0e392fca09b9fde11ecc061f5276fcf85db5d23c 100644
--- a/src/interfaces/jdbc/org/postgresql/PG_Stream.java
+++ b/src/interfaces/jdbc/org/postgresql/PG_Stream.java
@@ -22,7 +22,10 @@ public class PG_Stream
   private Socket connection;
   private InputStream pg_input;
   private BufferedOutputStream pg_output;
-  
+
+  public PGStatement executingStatement;
+
+
   /**
    * Constructor:  Connect to the PostgreSQL back end and return
    * a stream connection.
@@ -44,6 +47,15 @@ public class PG_Stream
     pg_output = new BufferedOutputStream(connection.getOutputStream(), 8192);
   }
   
+  /**
+   * Set the currently executing statement. This is used to bind cached byte 
+   * arrays to a Statement, so the statement can return the to the global 
+   * pool of unused byte arrays when they are no longer inuse.
+   */
+  public void setExecutingStatement(PGStatement executingStatement){
+      this.executingStatement = executingStatement;
+  }
+  
   /**
    * Sends a single character to the back end
    *
@@ -70,7 +82,7 @@ public class PG_Stream
    */
   public void SendInteger(int val, int siz) throws IOException
   {
-    byte[] buf = new byte[siz];
+    byte[] buf = allocByteDim1(siz);
     
     while (siz-- > 0)
       {
@@ -94,7 +106,7 @@ public class PG_Stream
    */
   public void SendIntegerReverse(int val, int siz) throws IOException
   {
-    byte[] buf = new byte[siz];
+    byte[] buf = allocByteDim1(siz);
     int p=0;
     while (siz-- > 0)
       {
@@ -236,23 +248,52 @@ public class PG_Stream
       return n;
   }
 
-    public String ReceiveString(int maxsize) throws SQLException {
-        return ReceiveString(maxsize, null);
-    }
-  
+
   /**
    * Receives a null-terminated string from the backend.  Maximum of
    * maxsiz bytes - if we don't see a null, then we assume something
    * has gone wrong.
    *
+   * @param maxsiz maximum length of string
+   * @return string from back end
+   * @exception SQLException if an I/O error occurs
+   */
+  public String ReceiveString(int maxsiz) throws SQLException
+  {
+    return ReceiveString(maxsiz, null);
+  }
+
+  /**
+   * Receives a null-terminated string from the backend.  Maximum of
+   * maxsiz bytes - if we don't see a null, then we assume something
+   * has gone wrong.
+   *
+   * @param maxsiz maximum length of string
    * @param encoding the charset encoding to use.
-   * @param maxsiz maximum length of string in bytes
    * @return string from back end
    * @exception SQLException if an I/O error occurs
    */
   public String ReceiveString(int maxsiz, String encoding) throws SQLException
   {
-    byte[] rst = new byte[maxsiz];
+    byte[] rst = allocByteDim1(maxsiz);
+    return ReceiveString(rst, maxsiz, encoding);
+  }
+  
+  /**
+   * Receives a null-terminated string from the backend.  Maximum of
+   * maxsiz bytes - if we don't see a null, then we assume something
+   * has gone wrong.
+   *
+   * @param rst byte array to read the String into. rst.length must 
+   *        equal to or greater than maxsize. 
+   * @param maxsiz maximum length of string in bytes
+   * @param encoding the charset encoding to use.
+   * @return string from back end
+   * @exception SQLException if an I/O error occurs
+   */
+  public String ReceiveString(byte rst[], int maxsiz, String encoding) 
+      throws SQLException
+  {
     int s = 0;
     
     try
@@ -262,9 +303,10 @@ public class PG_Stream
 	    int c = pg_input.read();
 	    if (c < 0)
 	      throw new PSQLException("postgresql.stream.eof");
-	    else if (c == 0)
-	      break;
-	    else
+	    else if (c == 0) {
+		rst[s] = 0;
+		break;
+	    } else
 	      rst[s++] = (byte)c;
 	  }
 	if (s >= maxsiz)
@@ -299,7 +341,7 @@ public class PG_Stream
   {
     int i, bim = (nf + 7)/8;
     byte[] bitmask = Receive(bim);
-    byte[][] answer = new byte[nf][0];
+    byte[][] answer = allocByteDim2(nf);
     
     int whichbit = 0x80;
     int whichbyte = 0;
@@ -337,7 +379,7 @@ public class PG_Stream
    */
   private byte[] Receive(int siz) throws SQLException
   {
-    byte[] answer = new byte[siz];
+    byte[] answer = allocByteDim1(siz);
     Receive(answer,0,siz);
     return answer;
   }
@@ -395,4 +437,95 @@ public class PG_Stream
     pg_input.close();
     connection.close();
   }
+
+  /**
+   * Deallocate all resources that has been associated with any previous
+   * query.
+   */
+  public void deallocate(PGStatement stmt){
+
+      for(int i = 0; i < maxsize_dim1; i++){
+	  synchronized(notusemap_dim1[i]){
+	      notusemap_dim1[i].addAll(stmt.inusemap_dim1[i]);
+	  }
+	  stmt.inusemap_dim1[i].clear();
+      }
+
+      for(int i = 0; i < maxsize_dim2; i++){
+	  synchronized(notusemap_dim2[i]){
+	      notusemap_dim2[i].addAll(stmt.inusemap_dim2[i]);
+	  }
+	  stmt.inusemap_dim2[i].clear();
+      }
+  }
+
+  public static final int maxsize_dim1 = 256;
+  public static ObjectPool notusemap_dim1[] = new ObjectPool[maxsize_dim1]; 
+  public static byte binit[][] = new byte[maxsize_dim1][0];
+  public static final int maxsize_dim2 = 32;
+  public static ObjectPool notusemap_dim2[] = new ObjectPool[maxsize_dim2]; 
+  public static ObjectPoolFactory factory_dim1;
+  public static ObjectPoolFactory factory_dim2;
+
+  static {
+      for(int i = 0; i < maxsize_dim1; i++){
+	  binit[i] = new byte[i];
+	  notusemap_dim1[i] = new ObjectPool();
+      }
+      for(int i = 0; i < maxsize_dim2; i++){
+	  notusemap_dim2[i] = new ObjectPool();
+      }
+      factory_dim1 = ObjectPoolFactory.getInstance(maxsize_dim1);
+      factory_dim2 = ObjectPoolFactory.getInstance(maxsize_dim2);
+  }
+
+  public byte[] allocByteDim1(int size){
+      if(size >= maxsize_dim1 || executingStatement == null){
+	  return new byte[size];
+      }
+      ObjectPool not_usel = notusemap_dim1[size];
+      ObjectPool in_usel = executingStatement.inusemap_dim1[size];
+
+      byte b[] = null;
+
+      synchronized(not_usel){
+	  if(!not_usel.isEmpty()) {
+	      Object o = not_usel.remove();
+	      b = (byte[]) o;
+	  } else {
+	      b = new byte[size];
+	  }
+      }
+      in_usel.add(b);
+
+      return b;
+  }    
+
+  public byte[][] allocByteDim2(int size){
+      if(size >= maxsize_dim2 || executingStatement == null){
+	  return new byte[size][0];
+      }
+      ObjectPool not_usel = notusemap_dim2[size];
+      ObjectPool in_usel = executingStatement.inusemap_dim2[size];
+
+      byte b[][] = null;
+      
+      synchronized(not_usel){
+	  if(!not_usel.isEmpty()) {
+	      Object o = not_usel.remove();
+	      b = (byte[][]) o;
+	  } else 
+	      b = new byte[size][0];
+	  
+	  in_usel.add(b);
+      }
+
+      return b;
+  }    
+
 }
+
+
+
+
+
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java
index f26057b52b302a430a7d009a5a4b666968c8bf2c..607c19145be450df51171ce5b8c9a7ae674ceb87 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java
@@ -17,7 +17,7 @@ import org.postgresql.largeobject.*;
 import org.postgresql.util.*;
 
 /**
- * $Id: Connection.java,v 1.2 2000/06/06 11:06:04 peter Exp $
+ * $Id: Connection.java,v 1.3 2000/10/08 19:37:54 momjian Exp $
  *
  * A Connection represents a session with a specific database.  Within the
  * context of a Connection, SQL statements are executed and results are
@@ -138,9 +138,9 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
     if (this.autoCommit == autoCommit)
       return;
     if (autoCommit)
-      ExecSQL("end");
+      ExecSQL(null, "end");
     else
-      ExecSQL("begin");
+      ExecSQL(null, "begin");
     this.autoCommit = autoCommit;
   }
   
@@ -170,9 +170,9 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
   {
     if (autoCommit)
       return;
-    ExecSQL("commit");
+    ExecSQL(null, "commit");
     autoCommit = true;
-    ExecSQL("begin");
+    ExecSQL(null, "begin");
     autoCommit = false;
   }
   
@@ -188,9 +188,9 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
   {
     if (autoCommit)
       return;
-    ExecSQL("rollback");
+    ExecSQL(null, "rollback");
     autoCommit = true;
-    ExecSQL("begin");
+    ExecSQL(null, "begin");
     autoCommit = false;
   }
   
@@ -316,11 +316,11 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
       switch(level) {
 	  
       case java.sql.Connection.TRANSACTION_READ_COMMITTED:
-	  ExecSQL(q + " READ COMMITTED");
+	  ExecSQL(null, q + " READ COMMITTED");
 	  return;
 	  
       case java.sql.Connection.TRANSACTION_SERIALIZABLE:
-	  ExecSQL(q + " SERIALIZABLE");
+	  ExecSQL(null, q + " SERIALIZABLE");
 	  return;
 	  
       default:
@@ -336,7 +336,7 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
    */
   public int getTransactionIsolation() throws SQLException
   {
-      ExecSQL("show xactisolevel");
+      ExecSQL(null, "show xactisolevel");
       
       SQLWarning w = getWarnings();
       if (w != null) {
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
index 674c0d16e1078ce6e9e23f6ebc4817f537e72340..ded0a17b164819e7b9197fda97de7a8577ae4a89 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
@@ -1497,7 +1497,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
     if(procedureNamePattern==null)
       procedureNamePattern="%";
     
-    r = connection.ExecSQL("select proname, proretset from pg_proc where proname like '"+procedureNamePattern.toLowerCase()+"' order by proname");
+    r = connection.ExecSQL(null, "select proname, proretset from pg_proc where proname like '"+procedureNamePattern.toLowerCase()+"' order by proname");
     
     while (r.next())
       {
@@ -1670,7 +1670,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
     sql.append("'");
     
     // Now run the query
-    r = connection.ExecSQL(sql.toString());
+    r = connection.ExecSQL(null, sql.toString());
     
     byte remarks[];
     
@@ -1679,7 +1679,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
 	byte[][] tuple = new byte[5][0];
 	
 	// Fetch the description for the table (if any)
-	java.sql.ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(2));
+	java.sql.ResultSet dr = connection.ExecSQL(null, "select description from pg_description where objoid="+r.getInt(2));
 	if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
 	  dr.next();
 	  remarks = dr.getBytes(1);
@@ -1893,7 +1893,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
     
     // Now form the query
     // Modified by Stefan Andreasen <stefan@linux.kapow.dk>
-    r = connection.ExecSQL("select a.oid,c.relname,a.attname,a.atttypid,a.attnum,a.attnotnull,a.attlen,a.atttypmod from pg_class c, pg_attribute a where a.attrelid=c.oid and c.relname like '"+tableNamePattern.toLowerCase()+"' and a.attname like '"+columnNamePattern.toLowerCase()+"' and a.attnum>0 order by c.relname,a.attnum");
+    r = connection.ExecSQL(null, "select a.oid,c.relname,a.attname,a.atttypid,a.attnum,a.attnotnull,a.attlen,a.atttypmod from pg_class c, pg_attribute a where a.attrelid=c.oid and c.relname like '"+tableNamePattern.toLowerCase()+"' and a.attname like '"+columnNamePattern.toLowerCase()+"' and a.attnum>0 order by c.relname,a.attnum");
     
     byte remarks[];
     
@@ -1901,7 +1901,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
 	byte[][] tuple = new byte[18][0];
 	
 	// Fetch the description for the table (if any)
-	java.sql.ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(1));
+	java.sql.ResultSet dr = connection.ExecSQL(null, "select description from pg_description where objoid="+r.getInt(1));
 	if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
 	  dr.next();
 	  tuple[11] = dr.getBytes(1);
@@ -1915,7 +1915,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
 	tuple[2] = r.getBytes(2);	// Table name
 	tuple[3] = r.getBytes(3);	// Column name
 	
-	dr = connection.ExecSQL("select typname from pg_type where oid = "+r.getString(4));
+	dr = connection.ExecSQL(null, "select typname from pg_type where oid = "+r.getString(4));
 	dr.next();
 	String typname=dr.getString(1);
 	dr.close();
@@ -2009,7 +2009,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
     f[7] = new Field(connection,"IS_GRANTABLE",iVarcharOid,32);
     
     // This is taken direct from the psql source
-    java.sql.ResultSet r = connection.ExecSQL("SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner and relname like '"+table.toLowerCase()+"' ORDER BY relname");
+    java.sql.ResultSet r = connection.ExecSQL(null, "SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner and relname like '"+table.toLowerCase()+"' ORDER BY relname");
     while(r.next()) {
       byte[][] tuple = new byte[8][0];
       tuple[0] = tuple[1]= "".getBytes();
@@ -2406,7 +2406,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
    */
   public java.sql.ResultSet getTypeInfo() throws SQLException
   {
-    java.sql.ResultSet rs = connection.ExecSQL("select typname from pg_type");
+    java.sql.ResultSet rs = connection.ExecSQL(null, "select typname from pg_type");
     if(rs!=null) {
       Field f[] = new Field[18];
       ResultSet r;	// ResultSet for the SQL query that we need to do
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java
index 43e5d381434ee7203d3732cf6478fe1a577a8b2c..dfba5c14decc99a9a38989b9e60f643092fe7aec 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java
@@ -6,6 +6,7 @@ package org.postgresql.jdbc1;
 // org.postgresql.jdbc2 package.
 
 import java.sql.*;
+import org.postgresql.PGStatement;
 
 import org.postgresql.util.PSQLException;
 
@@ -22,9 +23,8 @@ import org.postgresql.util.PSQLException;
  * @see java.sql.Statement
  * @see ResultSet
  */
-public class Statement implements java.sql.Statement
+public class Statement extends PGStatement implements java.sql.Statement
 {
-    Connection connection;		// The connection who created us
     java.sql.ResultSet result = null;	// The current results
     SQLWarning warnings = null;	// The warnings chain.
     int timeout = 0;		// The timeout for a query (not used)
@@ -38,7 +38,7 @@ public class Statement implements java.sql.Statement
 	 */
 	public Statement (Connection c)
 	{
-		connection = c;
+	    super(c);
 	}
 
 	/**
@@ -89,7 +89,8 @@ public class Statement implements java.sql.Statement
 	 */
 	public void close() throws SQLException
 	{
-		result = null;
+	    super.close();
+	    result = null;
 	}
 
 	/**
@@ -266,7 +267,8 @@ public class Statement implements java.sql.Statement
 	 */
 	public boolean execute(String sql) throws SQLException
 	{
-		result = connection.ExecSQL(sql);
+	    deallocate();
+		result = connection.ExecSQL(this, sql);
 		return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
 	}
 
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
index 43e7ee992d23140529ff2393414b579bfc7b4567..c00b4188659a6889409394f3e24f7da6e960bf49 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
@@ -17,7 +17,7 @@ import org.postgresql.largeobject.*;
 import org.postgresql.util.*;
 
 /**
- * $Id: Connection.java,v 1.2 2000/06/06 11:06:09 peter Exp $
+ * $Id: Connection.java,v 1.3 2000/10/08 19:37:55 momjian Exp $
  *
  * A Connection represents a session with a specific database.  Within the
  * context of a Connection, SQL statements are executed and results are
@@ -138,9 +138,9 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
     if (this.autoCommit == autoCommit)
       return;
     if (autoCommit)
-      ExecSQL("end");
+      ExecSQL(null, "end");
     else
-      ExecSQL("begin");
+      ExecSQL(null, "begin");
     this.autoCommit = autoCommit;
   }
   
@@ -170,9 +170,9 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
   {
     if (autoCommit)
       return;
-    ExecSQL("commit");
+    ExecSQL(null, "commit");
     autoCommit = true;
-    ExecSQL("begin");
+    ExecSQL(null, "begin");
     autoCommit = false;
   }
   
@@ -188,9 +188,9 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
   {
     if (autoCommit)
       return;
-    ExecSQL("rollback");
+    ExecSQL(null, "rollback");
     autoCommit = true;
-    ExecSQL("begin");
+    ExecSQL(null, "begin");
     autoCommit = false;
   }
   
@@ -316,11 +316,11 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
     switch(level) {
 
       case java.sql.Connection.TRANSACTION_READ_COMMITTED:
-        ExecSQL(q + " READ COMMITTED");
+        ExecSQL(null, q + " READ COMMITTED");
 	return;
       
       case java.sql.Connection.TRANSACTION_SERIALIZABLE:
-        ExecSQL(q + " SERIALIZABLE");
+        ExecSQL(null, q + " SERIALIZABLE");
 	return;
 
       default:
@@ -336,7 +336,7 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
    */
   public int getTransactionIsolation() throws SQLException
   {
-      ExecSQL("show xactisolevel");
+      ExecSQL(null, "show xactisolevel");
       
       SQLWarning w = getWarnings();
       if (w != null) {
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java b/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
index 4b8451d1fccfe1ee4dff166267c2e2d1864def30..3ff6c87b81027bdf41b6c65a183338a6335f4977 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
@@ -1497,7 +1497,8 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
     if(procedureNamePattern==null)
       procedureNamePattern="%";
     
-    r = connection.ExecSQL("select proname, proretset from pg_proc where proname like '"+procedureNamePattern.toLowerCase()+"' order by proname");
+    r = connection.ExecSQL(null, 
+			   "select proname, proretset from pg_proc where proname like '"+procedureNamePattern.toLowerCase()+"' order by proname");
     
     while (r.next())
       {
@@ -1670,7 +1671,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
     sql.append("'");
     
     // Now run the query
-    r = connection.ExecSQL(sql.toString());
+    r = connection.ExecSQL(null, sql.toString());
     
     byte remarks[];
     
@@ -1679,7 +1680,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
 	byte[][] tuple = new byte[5][0];
 	
 	// Fetch the description for the table (if any)
-	java.sql.ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(2));
+	java.sql.ResultSet dr = connection.ExecSQL(null, "select description from pg_description where objoid="+r.getInt(2));
 	if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
 	  dr.next();
 	  remarks = dr.getBytes(1);
@@ -1893,7 +1894,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
     
     // Now form the query
     // Modified by Stefan Andreasen <stefan@linux.kapow.dk>
-    r = connection.ExecSQL("select a.oid,c.relname,a.attname,a.atttypid,a.attnum,a.attnotnull,a.attlen,a.atttypmod from pg_class c, pg_attribute a where a.attrelid=c.oid and c.relname like '"+tableNamePattern.toLowerCase()+"' and a.attname like '"+columnNamePattern.toLowerCase()+"' and a.attnum>0 order by c.relname,a.attnum");
+    r = connection.ExecSQL(null, "select a.oid,c.relname,a.attname,a.atttypid,a.attnum,a.attnotnull,a.attlen,a.atttypmod from pg_class c, pg_attribute a where a.attrelid=c.oid and c.relname like '"+tableNamePattern.toLowerCase()+"' and a.attname like '"+columnNamePattern.toLowerCase()+"' and a.attnum>0 order by c.relname,a.attnum");
     
     byte remarks[];
     
@@ -1901,7 +1902,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
 	byte[][] tuple = new byte[18][0];
 	
 	// Fetch the description for the table (if any)
-	java.sql.ResultSet dr = connection.ExecSQL("select description from pg_description where objoid="+r.getInt(1));
+	java.sql.ResultSet dr = connection.ExecSQL(null, "select description from pg_description where objoid="+r.getInt(1));
 	if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
 	  dr.next();
 	  tuple[11] = dr.getBytes(1);
@@ -1915,7 +1916,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
 	tuple[2] = r.getBytes(2);	// Table name
 	tuple[3] = r.getBytes(3);	// Column name
 	
-	dr = connection.ExecSQL("select typname from pg_type where oid = "+r.getString(4));
+	dr = connection.ExecSQL(null, "select typname from pg_type where oid = "+r.getString(4));
 	dr.next();
 	String typname=dr.getString(1);
 	dr.close();
@@ -2009,7 +2010,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
     f[7] = new Field(connection,"IS_GRANTABLE",iVarcharOid,32);
     
     // This is taken direct from the psql source
-    java.sql.ResultSet r = connection.ExecSQL("SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner and relname like '"+table.toLowerCase()+"' ORDER BY relname");
+    java.sql.ResultSet r = connection.ExecSQL(null, "SELECT relname, relacl FROM pg_class, pg_user WHERE ( relkind = 'r' OR relkind = 'i') and relname !~ '^pg_' and relname !~ '^xin[vx][0-9]+' and usesysid = relowner and relname like '"+table.toLowerCase()+"' ORDER BY relname");
     while(r.next()) {
       byte[][] tuple = new byte[8][0];
       tuple[0] = tuple[1]= "".getBytes();
@@ -2406,7 +2407,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
    */
   public java.sql.ResultSet getTypeInfo() throws SQLException
   {
-    java.sql.ResultSet rs = connection.ExecSQL("select typname from pg_type");
+    java.sql.ResultSet rs = connection.ExecSQL(null, "select typname from pg_type");
     if(rs!=null) {
       Field f[] = new Field[18];
       ResultSet r;	// ResultSet for the SQL query that we need to do
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Statement.java
index 1da970fa88ca675db8c29bdf5941e0c8f21c3f93..8b6ca9a2986e0ec39f30aad57b17a788411ec9d3 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/Statement.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Statement.java
@@ -8,6 +8,7 @@ package org.postgresql.jdbc2;
 import java.sql.*;
 import java.util.Vector;
 import org.postgresql.util.*;
+import org.postgresql.PGStatement;
 
 /**
  * A Statement object is used for executing a static SQL statement and
@@ -22,9 +23,8 @@ import org.postgresql.util.*;
  * @see java.sql.Statement
  * @see ResultSet
  */
-public class Statement implements java.sql.Statement
+public class Statement extends PGStatement implements java.sql.Statement
 {
-    Connection connection;		// The connection who created us
     java.sql.ResultSet result = null;	// The current results
     SQLWarning warnings = null;	// The warnings chain.
     int timeout = 0;		// The timeout for a query (not used)
@@ -39,7 +39,7 @@ public class Statement implements java.sql.Statement
 	 */
 	public Statement (Connection c)
 	{
-		connection = c;
+	    super(c);
 	}
 
 	/**
@@ -90,7 +90,8 @@ public class Statement implements java.sql.Statement
 	 */
 	public void close() throws SQLException
 	{
-		result = null;
+	    super.close();
+	    result = null;
 	}
 
 	/**
@@ -269,8 +270,8 @@ public class Statement implements java.sql.Statement
     {
 	if(escapeProcessing)
 	    sql=connection.EscapeSQL(sql);
-	
-	result = connection.ExecSQL(sql);
+	deallocate();
+	result = connection.ExecSQL(this, sql);
 	return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
     }
     
diff --git a/src/interfaces/jdbc/org/postgresql/util/Serialize.java b/src/interfaces/jdbc/org/postgresql/util/Serialize.java
index 3af43e6eb840e8a93391eea6411ce02b0fbc2b38..08bc2185148d12ee1a13aacf80848857324fcad6 100644
--- a/src/interfaces/jdbc/org/postgresql/util/Serialize.java
+++ b/src/interfaces/jdbc/org/postgresql/util/Serialize.java
@@ -50,7 +50,7 @@ public class Serialize
     
     // Second check, the type must be a table
     boolean status = false;
-    ResultSet rs = conn.ExecSQL("select typname from pg_type,pg_class where typname=relname and typname='"+type+"'");
+    ResultSet rs = conn.ExecSQL(null, "select typname from pg_type,pg_class where typname=relname and typname='"+type+"'");
     if(rs!=null) {
       if(rs.next())
 	status=true;
@@ -97,7 +97,7 @@ public class Serialize
       sb.append(oid);
       
       DriverManager.println("store: "+sb.toString());
-      ResultSet rs = conn.ExecSQL(sb.toString());
+      ResultSet rs = conn.ExecSQL(null, sb.toString());
       if(rs!=null) {
 	if(rs.next()) {
 	  for(int i=0;i<f.length;i++) {
@@ -189,7 +189,7 @@ public class Serialize
       }
       
       DriverManager.println("store: "+sb.toString());
-      ResultSet rs = conn.ExecSQL(sb.toString());
+      ResultSet rs = conn.ExecSQL(null, sb.toString());
       if(rs!=null) {
 	rs.close();
       }
@@ -236,7 +236,7 @@ public class Serialize
     // See if the table exists
     String tableName = toPostgreSQL(c.getName());
     
-    ResultSet rs = con.ExecSQL("select relname from pg_class where relname = '"+tableName+"'");
+    ResultSet rs = con.ExecSQL(null, "select relname from pg_class where relname = '"+tableName+"'");
     if(!rs.next()) {
       DriverManager.println("found "+rs.getString(1));
       // No entries returned, so the table doesn't exist
@@ -277,7 +277,7 @@ public class Serialize
       
       // Now create the table
       DriverManager.println("Serialize.create:"+sb);
-      con.ExecSQL(sb.toString());
+      con.ExecSQL(null, sb.toString());
       rs.close();
     } else {
       DriverManager.println("Serialize.create: table "+tableName+" exists, skipping");