gt: 	        Statement stmt2 = createStatement();
context: /*
   * This file is part of Splice Machine.
   * Splice Machine is free software: you can redistribute it and/or modify it under the terms of the
   * GNU Affero General Public License as published by the Free Software Foundation, either
   * version 3, or (at your option) any later version.
   * Splice Machine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
   * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   * See the GNU Affero General Public License for more details.
   * You should have received a copy of the GNU Affero General Public License along with Splice Machine.
   * If not, see <http://www.gnu.org/licenses/>.
   *
   * Some parts of this source code are based on Apache Derby, and the following notices apply to
   * Apache Derby:
   *
   * Apache Derby is a subproject of the Apache DB project, and is licensed under
   * the Apache License, Version 2.0 (the "License"); you may not use these files
   * except in compliance with the License. You may obtain a copy of the License at:
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software distributed
   * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   * CONDITIONS OF ANY KIND, either express or implied. See the License for the
   * specific language governing permissions and limitations under the License.
   *
   * Splice Machine, Inc. has modified the Apache Derby code in this file.
   *
   * All such Splice Machine modifications are Copyright 2012 - 2020 Splice Machine, Inc.,
   * and are licensed to you under the GNU Affero General Public License.
   */
  
  package com.splicemachine.dbTesting.functionTests.tests.lang;
  
  import java.sql.PreparedStatement;
  import java.sql.CallableStatement;
  import java.sql.ResultSet;
  import java.sql.Connection;
  import java.sql.SQLException;
  import java.sql.Statement;
  import java.sql.DriverManager;
  import junit.framework.Test;
  import junit.framework.TestSuite;
  
  import com.splicemachine.dbTesting.junit.BaseJDBCTestCase;
  import com.splicemachine.dbTesting.junit.JDBC;
  import com.splicemachine.dbTesting.junit.CleanDatabaseTestSetup;
  import com.splicemachine.dbTesting.junit.TestConfiguration;
  
  /**
   * Test hold cursor after commit
   */
  public class HoldCursorTest extends BaseJDBCTestCase {
  	/**
       * Public constructor required for running test as standalone JUnit.
       */
  	public HoldCursorTest(String name) {
  		super(name);
  	}
  	/**
       * Create a suite of tests.
       */
      public static Test suite() {
          TestSuite suite = new TestSuite("HoldCursorTest");
  
          suite.addTest(baseSuite(true));
          suite.addTest(baseSuite(false));
  
          return suite;
      }
  
      private static Test baseSuite(boolean embeddedMode) {
          String name = "HoldCursorTest:" + (embeddedMode ? "embedded" : "client");
          TestSuite suite = new TestSuite(name);
  
          // Add tests that every JVM jdk1.4 or above should be able to run.
          suite.addTestSuite(HoldCursorTest.class);
  
          if (!JDBC.vmSupportsJSR169()) {
               suite.addTest (new HoldCursorTest("StatementsInProcedureTest"));
          }
  
          Test test = suite;
  
          if (!embeddedMode) {
              test = TestConfiguration.clientServerDecorator(suite);
          }
  
          return new CleanDatabaseTestSetup(test);
      }
  
      /**
       * Set the fixture up with tables and insert rows .
       */
  	protected void setUp() throws SQLException {
  		getConnection().setAutoCommit(false);
  		Statement stmt = createStatement();
  		final int stringLength = 400;
  	    stmt.executeUpdate("CREATE TABLE T1 (c11 int, c12 int, junk varchar(" +
  	                       stringLength + "))");
  	    PreparedStatement insertStmt = prepareStatement("INSERT INTO T1 VALUES(?,1,?)");
  	    // We need to ensure that there is more data in the table than the
  	    // client can fetch in one message (about 32K). Otherwise, the
  	    // cursor might be closed on the server and we are not testing the
  	    // same thing in embedded mode and client/server mode.
  	    final int rows = 40000 / stringLength;
  	    StringBuffer buff = new StringBuffer(stringLength);
  	    for (int i = 0; i < stringLength; i++) {
  	        buff.append(" ");
  	    }
  	    for (int i = 1; i <= rows; i++) {
  	        insertStmt.setInt(1, i);
  	        insertStmt.setString(2, buff.toString());
  	        insertStmt.executeUpdate();
  	    }
  	    insertStmt.close();
  	    stmt.executeUpdate( "CREATE TABLE T2 (c21 int, c22 int)" );
  	    stmt.executeUpdate("INSERT INTO T2 VALUES(1,1)");
  	    stmt.executeUpdate("INSERT INTO T2 VALUES(1,2)");
  	    stmt.executeUpdate("INSERT INTO T2 VALUES(1,3)");
  	    stmt.execute("create table testtable1 (id integer, vc varchar(100))");
  	    stmt.execute("insert into testtable1 values (11, 'testtable1-one'), (12, 'testtable1-two')");
  	    stmt.execute("create table testtable2 (id integer, vc varchar(100))");
  	    stmt.execute("insert into testtable2 values (21, 'testtable2-one'), (22, 'testtable2-two')");
  	    stmt.execute("create procedure MYPROC() language java parameter style java external name " +
  	    				"'com.splicemachine.dbTesting.functionTests.tests.lang.HoldCursorTest.testProc' result sets 2");
  	    stmt.executeUpdate("Create table bug4385 (i int not null primary key, c int generated always as identity)");
  	    stmt.close();
  	    commit();		
  	}
  	/**
  	 * Drop tables for clean up
  	 */
  	protected void tearDown() throws Exception {
  		Statement stmt = createStatement();
  		stmt.executeUpdate( "DROP PROCEDURE MYPROC" );
  	    stmt.executeUpdate( "DROP TABLE T1" );
  	    stmt.executeUpdate( "DROP TABLE T2" );
  	    stmt.executeUpdate( "DROP TABLE testtable1" );
  	    stmt.executeUpdate( "DROP TABLE testtable2" );
  	    stmt.executeUpdate( "DROP TABLE BUG4385" );
  	    stmt.close();
  	    stmt.close();
  		commit();
  		super.tearDown();
  	}
  	/**
  	 * test cursor holdability after commit on multi table query
  	 * @throws Exception
  	 */
  	 public void testHoldCursorOnMultiTableQuery() throws Exception
  	  {
  	    ResultSet	rs;
  	    Statement s = createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT );
  
  	    //open a cursor with multiple rows resultset
  	    rs = s.executeQuery("select t1.c11, t2.c22 from t1, t2 where t1.c11=t2.c21");
  	    rs.next();
  	    assertEquals("1", rs.getString(2));
  	    commit();
  	    rs.next(); //because holdability is true, should be able to navigate the cursor after commit
  	    assertEquals("2", rs.getString(2));
  	    rs.close();
  	 }
  	 /**
  	  * Test Chaging isolation levels with and without held curosors
  	  * @throws Exception
  	  */
  	 public void testIsolationLevelChange() throws Exception
  	  {
  	     ResultSet	rs;
  	    //set current isolation to read committed
  	    setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
  	    Statement s = createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,ResultSet.HOLD_CURSORS_OVER_COMMIT );
  	    //open a cursor with multiple rows resultset
  	    rs = s.executeQuery("select * from t1");
  	    rs.next();
  
  	    //Changing to different isolation from the current isolation for connection
  	    //will give an exception because there are held cursors
  		assertIsolationError("X0X03",Connection.TRANSACTION_SERIALIZABLE);
  
  	    //Close open cursors and then try changing to different isolation.
  	    //It should work.
  	    rs.close();
  	    setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
  
  		// set the default holdability for the Connection and try setting the isolation level
  		setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
  		setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
  		createStatement().executeUpdate("SET ISOLATION RS");
  
  			// test for bug4385 - internal ResultSets were being re-used incorrectly
  			// will occur in with JDBC 2.0,1.2 but the first statement I found that
  			// failed was an insert with generated keys.
  			
  		PreparedStatement ps = prepareStatement("insert into bug4385(i) values(?)", Statement.RETURN_GENERATED_KEYS);
  		ps.setInt(1, 199);
  		ps.executeUpdate();
  		assertGetIntEquals(1,1,ps.getGeneratedKeys());
  		rs.close();
  		
  		ps.setInt(1, 299);
  		ps.executeUpdate();
  		assertGetIntEquals(1,2,ps.getGeneratedKeys());
  		rs.close();
  		ps.close();
  		rollback();
  
  	    //switch back to default isolation & holdability
  		setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
  		setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
  	 }
  	 /**
  	     * Test that drop table cannot be performed when there is an open
  	     * cursor on that table.
  	     *
  	     * @exception SQLException 
  	     */
  	    public void testDropTable() throws SQLException {
  	        setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
  	        final String dropTable = "DROP TABLE T1";
  	        Statement stmt1 = createStatement();
  