? built ? jdbcbuild.sh ? transstate.74.patch Index: org/postgresql/errors.properties =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/Attic/errors.properties,v retrieving revision 1.25 diff -c -r1.25 errors.properties *** org/postgresql/errors.properties 17 Sep 2003 05:14:51 -0000 1.25 --- org/postgresql/errors.properties 30 Apr 2004 16:58:49 -0000 *************** *** 28,33 **** --- 28,34 ---- postgresql.con.strobjex:Failed to store object - {0} postgresql.con.toolong:The SQL Statement is too long - {0} postgresql.con.isolevel:Transaction isolation level {0} is not supported. + postgresql.con.changeisolevel:Cannot change transaction isolation level in the middle of a transaction. postgresql.con.tuple:Tuple received before MetaData. postgresql.con.type:Unknown Response Type {0} postgresql.con.user:The user property is missing. It is mandatory. Index: org/postgresql/core/BaseConnection.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/core/Attic/BaseConnection.java,v retrieving revision 1.4 diff -c -r1.4 BaseConnection.java *** org/postgresql/core/BaseConnection.java 29 Oct 2003 02:39:09 -0000 1.4 --- org/postgresql/core/BaseConnection.java 30 Apr 2004 16:58:49 -0000 *************** *** 27,32 **** --- 27,35 ---- public Statement createStatement() throws SQLException; public BaseResultSet execSQL(String s) throws SQLException; public boolean getAutoCommit(); + public boolean getInTransaction(); + public void setInTransaction(boolean b); + public String getPre71IsolationLevelSQL() throws SQLException; public String getCursorName() throws SQLException; public Encoding getEncoding() throws SQLException; public DatabaseMetaData getMetaData() throws SQLException; Index: org/postgresql/core/QueryExecutor.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/core/Attic/QueryExecutor.java,v retrieving revision 1.27.2.2 diff -c -r1.27.2.2 QueryExecutor.java *** org/postgresql/core/QueryExecutor.java 29 Mar 2004 17:47:47 -0000 1.27.2.2 --- org/postgresql/core/QueryExecutor.java 30 Apr 2004 16:58:49 -0000 *************** *** 40,45 **** --- 40,53 ---- qe.connection = statement.getPGConnection(); qe.pgStream = qe.connection.getPGStream(); + if (!qe.connection.getAutoCommit() && !qe.connection.getInTransaction()) { + qe.connection.setInTransaction(true); + QueryExecutor.execute(new String[] {"BEGIN;"}, new Object[0], statement); + if (!qe.connection.haveMinimumServerVersion("7.1")) { + QueryExecutor.execute(new String[] {qe.connection.getPre71IsolationLevelSQL()}, new Object[0], statement); + } + } + return qe.execute(); } *************** *** 63,68 **** --- 71,84 ---- qe.connection = qe.statement.getPGConnection(); qe.pgStream = qe.connection.getPGStream(); + + if (!qe.connection.getAutoCommit() && !qe.connection.getInTransaction()) { + qe.connection.setInTransaction(true); + QueryExecutor.execute(new String[] {"BEGIN;"}, new Object[0], rs); + if (!qe.connection.haveMinimumServerVersion("7.1")) { + QueryExecutor.execute(new String[] {qe.connection.getPre71IsolationLevelSQL()}, new Object[0], rs); + } + } qe.execute(); } Index: org/postgresql/jdbc1/AbstractJdbc1Connection.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v retrieving revision 1.27.2.2 diff -c -r1.27.2.2 AbstractJdbc1Connection.java *** org/postgresql/jdbc1/AbstractJdbc1Connection.java 10 Feb 2004 01:58:48 -0000 1.27.2.2 --- org/postgresql/jdbc1/AbstractJdbc1Connection.java 30 Apr 2004 16:58:49 -0000 *************** *** 71,76 **** --- 71,77 ---- public boolean CONNECTION_BAD = false; public boolean autoCommit = true; + public boolean inTransaction = false; public boolean readOnly = false; public Driver this_driver; *************** *** 1255,1275 **** { if (this.autoCommit == autoCommit) return ; ! if (autoCommit) { ! execSQL("end"); ! } ! else ! { ! if (haveMinimumServerVersion("7.1")) ! { ! execSQL("begin;" + getIsolationLevelSQL()); ! } ! else ! { ! execSQL("begin"); ! execSQL(getIsolationLevelSQL()); ! } } this.autoCommit = autoCommit; } --- 1256,1265 ---- { if (this.autoCommit == autoCommit) return ; ! if (autoCommit && inTransaction) { ! execSQL("end"); ! inTransaction = false; } this.autoCommit = autoCommit; } *************** *** 1285,1290 **** --- 1275,1290 ---- return this.autoCommit; } + public boolean getInTransaction() + { + return this.inTransaction; + } + + public void setInTransaction(boolean inTransaction) + { + this.inTransaction = inTransaction; + } + /* * The method commit() makes all changes made since the previous * commit/rollback permanent and releases any database locks currently *************** *** 1299,1314 **** { if (autoCommit) return ; ! //TODO: delay starting new transaction until first command ! if (haveMinimumServerVersion("7.1")) ! { ! execSQL("commit;begin;" + getIsolationLevelSQL()); ! } ! else ! { ! execSQL("commit"); ! execSQL("begin"); ! execSQL(getIsolationLevelSQL()); } } --- 1299,1307 ---- { if (autoCommit) return ; ! if (inTransaction) { ! execSQL("commit;"); ! inTransaction = false; } } *************** *** 1324,1339 **** { if (autoCommit) return ; ! //TODO: delay starting transaction until first command ! if (haveMinimumServerVersion("7.1")) ! { ! execSQL("rollback; begin;" + getIsolationLevelSQL()); ! } ! else ! { execSQL("rollback"); ! execSQL("begin"); ! execSQL(getIsolationLevelSQL()); } } --- 1317,1325 ---- { if (autoCommit) return ; ! if (inTransaction) { execSQL("rollback"); ! inTransaction = false; } } *************** *** 1393,1463 **** */ public void setTransactionIsolation(int level) throws SQLException { //In 7.1 and later versions of the server it is possible using //the "set session" command to set this once for all future txns //however in 7.0 and prior versions it is necessary to set it in //each transaction, thus adding complexity below. //When we decide to drop support for servers older than 7.1 //this can be simplified - isolationLevel = level; String isolationLevelSQL; if (!haveMinimumServerVersion("7.1")) { ! isolationLevelSQL = getIsolationLevelSQL(); } else { ! isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL "; ! switch (isolationLevel) ! { ! case Connection.TRANSACTION_READ_COMMITTED: ! isolationLevelSQL += "READ COMMITTED"; ! break; ! case Connection.TRANSACTION_SERIALIZABLE: ! isolationLevelSQL += "SERIALIZABLE"; ! break; ! default: ! throw new PSQLException("postgresql.con.isolevel", PSQLState.TRANSACTION_STATE_INVALID, ! new Integer(isolationLevel)); } } ! execSQL(isolationLevelSQL); } ! /* ! * Helper method used by setTransactionIsolation(), commit(), rollback() ! * and setAutoCommit(). This returns the SQL string needed to ! * set the isolation level for a transaction. In 7.1 and later it ! * is possible to set a default isolation level that applies to all ! * future transactions, this method is only necesary for 7.0 and older ! * servers, and should be removed when support for these older ! * servers are dropped ! */ ! protected String getIsolationLevelSQL() throws SQLException { ! //7.1 and higher servers have a default specified so ! //no additional SQL is required to set the isolation level ! if (haveMinimumServerVersion("7.1")) ! { ! return ""; ! } ! StringBuffer sb = new StringBuffer("SET TRANSACTION ISOLATION LEVEL"); ! ! switch (isolationLevel) ! { ! case Connection.TRANSACTION_READ_COMMITTED: ! sb.append(" READ COMMITTED"); ! break; ! ! case Connection.TRANSACTION_SERIALIZABLE: ! sb.append(" SERIALIZABLE"); ! break; ! default: ! throw new PSQLException("postgresql.con.isolevel", PSQLState.TRANSACTION_STATE_INVALID, new Integer(isolationLevel)); } ! return sb.toString(); } /* --- 1379,1432 ---- */ public void setTransactionIsolation(int level) throws SQLException { + if (inTransaction) { + throw new PSQLException("postgresql.con.changeisolevel"); + } //In 7.1 and later versions of the server it is possible using //the "set session" command to set this once for all future txns //however in 7.0 and prior versions it is necessary to set it in //each transaction, thus adding complexity below. //When we decide to drop support for servers older than 7.1 //this can be simplified String isolationLevelSQL; if (!haveMinimumServerVersion("7.1")) { ! // Do nothing because we will do this on each ! // transaction. Still we want to check that it ! // is a valid level. ! String name = getIsolationLevelName(level); } else { ! isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL " + getIsolationLevelName(level); ! // We want to run this statement outside of any ! // transactions so that it can't be rolled back or ! // anything. The inTransaction check at the top ! // makes this autocommit flipping legal if ugly. ! boolean origAutoCommit = autoCommit; ! if (autoCommit == false) { ! setAutoCommit(true); } + execSQL(isolationLevelSQL); + setAutoCommit(origAutoCommit); } ! isolationLevel = level; } ! public String getPre71IsolationLevelSQL() throws SQLException { ! return "SET TRANSACTION ISOLATION LEVEL " + getIsolationLevelName(isolationLevel); ! } ! protected String getIsolationLevelName(int level) throws SQLException ! { ! if (level == Connection.TRANSACTION_READ_COMMITTED) { ! return " READ COMMITTED"; ! } else if (level == Connection.TRANSACTION_SERIALIZABLE) { ! return " SERIALIZABLE"; } ! throw new PSQLException("postgresql.con.isolevel", PSQLState.TRANSACTION_STATE_INVALID, new Integer(level)); } /* Index: org/postgresql/test/jdbc2/ConnectionTest.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/test/jdbc2/Attic/ConnectionTest.java,v retrieving revision 1.10.6.1 diff -c -r1.10.6.1 ConnectionTest.java *** org/postgresql/test/jdbc2/ConnectionTest.java 24 Feb 2004 13:11:44 -0000 1.10.6.1 --- org/postgresql/test/jdbc2/ConnectionTest.java 30 Apr 2004 16:58:49 -0000 *************** *** 227,236 **** /* * Transaction Isolation Levels */ ! public void testTransactionIsolation() { - try - { Connection con = TestUtil.openDB(); // PostgreSQL defaults to READ COMMITTED --- 227,234 ---- /* * Transaction Isolation Levels */ ! public void testTransactionIsolation() throws SQLException { Connection con = TestUtil.openDB(); // PostgreSQL defaults to READ COMMITTED *************** *** 245,285 **** con.getTransactionIsolation()); - // Note the behavior on when a transaction starts is different - // under 7.3 than previous versions. In 7.3 a transaction - // starts with the first sql command, whereas previously - // you were always in a transaction in autocommit=false - // so we issue a select to ensure we are in a transaction Statement stmt = con.createStatement(); - stmt.executeQuery("select 1"); - - // Now change the default for future transactions - con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); - - // Since the call to setTransactionIsolation() above was made - // inside the transaction, the isolation level of the current - // transaction did not change. It affects only future ones. - // This behaviour is recommended by the JDBC spec. - assertEquals(Connection.TRANSACTION_READ_COMMITTED, - con.getTransactionIsolation()); - - // Begin a new transaction - con.commit(); - stmt.executeQuery("select 1"); - - // Now we should see the new isolation level - assertEquals(Connection.TRANSACTION_SERIALIZABLE, - con.getTransactionIsolation()); - - // Repeat the steps above with the transition back to - // READ COMMITTED. - con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - assertEquals(Connection.TRANSACTION_SERIALIZABLE, - con.getTransactionIsolation()); - con.commit(); - assertEquals(Connection.TRANSACTION_READ_COMMITTED, - con.getTransactionIsolation()); - // Now run some tests with autocommit enabled. con.setAutoCommit(true); --- 243,249 ---- *************** *** 312,322 **** con.getTransactionIsolation()); TestUtil.closeDB(con); - } - catch ( SQLException ex ) - { - fail( ex.getMessage() ); - } } /* --- 276,281 ----