]> granicus.if.org Git - postgresql/commitdiff
Okay, I have some new code in place that hopefully should work better. I
authorBruce Momjian <bruce@momjian.us>
Sun, 8 Oct 2000 19:37:56 +0000 (19:37 +0000)
committerBruce Momjian <bruce@momjian.us>
Sun, 8 Oct 2000 19:37:56 +0000 (19:37 +0000)
couldn't produce a full patch using cvs diff -c this time since I have
created new files and anonymous cvs usage doesn't allow you to
adds. I'm supplying the modified src/interfaces/jdbc as a tarball at :
http://www.candleweb.no/~gunnar/projects/pgsql/postgres-jdbc-2000-10-05.tgz

The new files that should be added are :

? org/postgresql/PGStatement.java
? org/postgresql/ObjectPool.java
? org/postgresql/ObjectPoolFactory.java

There is now a global static pool of free byte arrays and used byte arrays
connected to a statement object. This is the role of the new PGStatement
class. Access to the global free array is synchronized, while we rely on
the PG_Stream synchronization for the used array.

My measurements show that the perfomance boost on this code is not quite as
big as my last shot, but it is still an improvement. Maybe some of the
difference is due to the new synchronization on the global array. I think I
will look into choosing between on a connection level and global level.

I have also started experimented with improving the performance of the
various conversions. The problem here is ofcourse related handle the
various encodings. One thing I found to speed up ResultSet.getInt() a lot
was to do custom conversion on the byte array into int instead of going
through the getString() to do the conversion. But I'm unsure if this is
portable, can we assume that a digit never can be represented by more than
one byte ? It works fine in my iso-latin-8859-1 environment, but what about
other environments ? Maybe we could provide different ResultSet
implementations depending on the encoding used or delegate some methods of
the result set to an "converter class".

Check the org/postgresql/jdbc2/FastResultSet.java in the tarball above to
see the modified getInt() method.

Regards,

        Gunnar

13 files changed:
src/interfaces/jdbc/org/postgresql/Connection.java
src/interfaces/jdbc/org/postgresql/Field.java
src/interfaces/jdbc/org/postgresql/ObjectPool.java [new file with mode: 0644]
src/interfaces/jdbc/org/postgresql/ObjectPoolFactory.java [new file with mode: 0644]
src/interfaces/jdbc/org/postgresql/PGStatement.java [new file with mode: 0644]
src/interfaces/jdbc/org/postgresql/PG_Stream.java
src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java
src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java
src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
src/interfaces/jdbc/org/postgresql/jdbc2/Statement.java
src/interfaces/jdbc/org/postgresql/util/Serialize.java

index fc908a43e9ef0f1718b1e74e451840625602e6af..198a7962a185932f92b3e5e968a8a8e10559ecdb 100644 (file)
@@ -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);
index b73c224e51faa080a242b3a01204d578dff3c371..6e3edab1be7fc4463091ca29d2b47ca7d46c79a4 100644 (file)
@@ -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 (file)
index 0000000..8ab4506
--- /dev/null
@@ -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 (file)
index 0000000..404c366
--- /dev/null
@@ -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 (file)
index 0000000..85fd5a5
--- /dev/null
@@ -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);
+    }
+}
index 22c41bdb3a3ab3de14742117d612770270fc5c08..0e392fca09b9fde11ecc061f5276fcf85db5d23c 100644 (file)
@@ -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;
+  }    
+
 }
+
+
+
+
+
index f26057b52b302a430a7d009a5a4b666968c8bf2c..607c19145be450df51171ce5b8c9a7ae674ceb87 100644 (file)
@@ -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) {
index 674c0d16e1078ce6e9e23f6ebc4817f537e72340..ded0a17b164819e7b9197fda97de7a8577ae4a89 100644 (file)
@@ -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
index 43e5d381434ee7203d3732cf6478fe1a577a8b2c..dfba5c14decc99a9a38989b9e60f643092fe7aec 100644 (file)
@@ -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());
        }
 
index 43e7ee992d23140529ff2393414b579bfc7b4567..c00b4188659a6889409394f3e24f7da6e960bf49 100644 (file)
@@ -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) {
index 4b8451d1fccfe1ee4dff166267c2e2d1864def30..3ff6c87b81027bdf41b6c65a183338a6335f4977 100644 (file)
@@ -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
index 1da970fa88ca675db8c29bdf5941e0c8f21c3f93..8b6ca9a2986e0ec39f30aad57b17a788411ec9d3 100644 (file)
@@ -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());
     }
     
index 3af43e6eb840e8a93391eea6411ce02b0fbc2b38..08bc2185148d12ee1a13aacf80848857324fcad6 100644 (file)
@@ -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");