diff --git a/src/interfaces/jdbc/org/postgresql/Connection.java b/src/interfaces/jdbc/org/postgresql/Connection.java index fc908a43e9..198a7962a1 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 * Note: 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 b73c224e51..6e3edab1be 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 0000000000..8ab4506c21 --- /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 0000000000..404c366daa --- /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 0000000000..85fd5a5b85 --- /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 22c41bdb3a..0e392fca09 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. + * @return string from back end + * @exception SQLException if an I/O error occurs + */ + public String ReceiveString(int maxsiz, String encoding) throws SQLException + { + 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 encoding the charset encoding to use. + * @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(int maxsiz, String encoding) throws SQLException + public String ReceiveString(byte rst[], int maxsiz, String encoding) + throws SQLException { - byte[] rst = new byte[maxsiz]; 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 f26057b52b..607c19145b 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 674c0d16e1..ded0a17b16 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 - 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 43e5d38143..dfba5c14de 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 43e7ee992d..c00b418865 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 4b8451d1fc..3ff6c87b81 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 - 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 1da970fa88..8b6ca9a298 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 3af43e6eb8..08bc218514 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