Search in sources :

Example 1 with StatementImpl

use of com.mysql.cj.jdbc.StatementImpl in project JavaSegundasQuintas by ecteruel.

the class StatementRegressionTest method testBug80615.

/**
 * Tests fix for Bug#80615 - prepared statement leak when rewriteBatchedStatements=true and useServerPrepStmt.
 *
 * There are two bugs here:
 * 1. A server prepared statement leakage by not actually closing the statement on server when .close() is called in the client side. This occurs when
 * setting 'cachePrepStmts=true&useServerPrepStmts=true' and a prepared statement is set as non-poolable ('setPoolable(false)'). By itself this doesn't
 * cause any visible issue because the connector has a fail-safe mechanism that uses client-side prepared statements when server-side prepared statements
 * fail to be prepared. So, the connector ends up using client-side prepared statements after the number of open prepared statements on server hits the
 * value of 'max_prepared_stmt_count'.
 * 2. A prepared statement fails to be prepared when there are too many open prepared statements on server. By setting the options
 * 'rewriteBatchedStatements=true&useServerPrepStmts=true' when a query happens to be rewritten a new (server-side) prepared statement is required but the
 * fail-safe mechanism isn't implemented in this spot, so, since the leakage described above already consumed all available prepared statements on server,
 * this ends up throwing the exception.
 *
 * This test combines three elements:
 * 1. Call .close() on a server prepared statement. This promotes a prepared statement for caching if prepared statements cache is enabled.
 * 2. cachePrepStmts=true|false. Turns on/off the prepared statements cache.
 * 3. Call .setPoolable(true|false) on the prepared statement. This allows canceling the prepared statement caching, on a per statement basis. It has no
 * effect if the prepared statements cache if turned off for the current connection.
 *
 * Expected behavior:
 * - If .close() is not called on server prepared statements then they also can't be promoted for caching. This causes a server prepared statements leak in
 * all remaining combinations.
 * - If .close() is called on server prepared statements and the prepared statements cache is disabled by any form (either per connection or per statement),
 * then the statements is immediately closed on server side too.
 * - If .close() is called on server prepared statements and the prepared statements cache is enabled (both in the connection and in the statement) then the
 * statement is cached and only effectively closed in the server side if and when removed from the cache.
 *
 * @throws Exception
 */
@Test
public void testBug80615() throws Exception {
    final int prepStmtCacheSize = 5;
    final int maxPrepStmtCount = 25;
    final int testRepetitions = maxPrepStmtCount + 5;
    int maxPrepStmtCountOri = -1;
    try {
        // Check if it is possible to create a server prepared statement with the current max_prepared_stmt_count.
        Properties props = new Properties();
        props.setProperty(PropertyKey.useSSL.getKeyName(), "false");
        props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        props.setProperty(PropertyKey.useServerPrepStmts.getKeyName(), "true");
        Connection checkConn = getConnectionWithProps(props);
        PreparedStatement checkPstmt = checkConn.prepareStatement("SELECT 1");
        assertTrue(checkPstmt instanceof ServerPreparedStatement, "Failed to create a server prepared statement possibly because there are too many active prepared statements on server already.");
        checkPstmt.close();
        this.rs = this.stmt.executeQuery("SELECT @@GLOBAL.max_prepared_stmt_count");
        this.rs.next();
        maxPrepStmtCountOri = this.rs.getInt(1);
        this.stmt.execute("SET GLOBAL max_prepared_stmt_count = " + maxPrepStmtCount);
        this.stmt.execute("FLUSH STATUS");
        // 2 - The statement that triggers the expelling of the oldest element of the cache to get room for itself.
        for (int i = 1; i <= prepStmtCacheSize + 2; i++) {
            checkPstmt = checkConn.prepareStatement("SELECT " + i);
            assertTrue(checkPstmt instanceof ServerPreparedStatement, "Test ABORTED because the server doesn't allow preparing at least " + (prepStmtCacheSize + 2) + " more statements.");
        }
        // Also closes all prepared statements.
        checkConn.close();
        // Good to go, start the test.
        boolean closeStmt = false;
        boolean useCache = false;
        boolean poolable = false;
        do {
            final String testCase = String.format("Case: [Close STMTs: %s, Use cache: %s, Poolable: %s ]", closeStmt ? "Y" : "N", useCache ? "Y" : "N", poolable ? "Y" : "N");
            System.out.println();
            System.out.println(testCase);
            System.out.println("********************************************************************************");
            createTable("testBug80615", "(id INT)");
            props.setProperty(PropertyKey.rewriteBatchedStatements.getKeyName(), "true");
            props.setProperty(PropertyKey.cachePrepStmts.getKeyName(), Boolean.toString(useCache));
            if (useCache) {
                props.setProperty(PropertyKey.prepStmtCacheSize.getKeyName(), String.valueOf(prepStmtCacheSize));
            }
            final Connection testConn = getConnectionWithProps(props);
            final Statement checkStmt = testConn.createStatement();
            // Prepare a statement to be executed later. This is prepare #1.
            PreparedStatement testPstmt1 = testConn.prepareStatement("INSERT INTO testBug80615 VALUES (?)");
            assertTrue(testPstmt1 instanceof ServerPreparedStatement, testCase);
            // Need to cast, this is a JDBC 4.0 feature.
            ((StatementImpl) testPstmt1).setPoolable(poolable);
            testPstmt1.setInt(1, 100);
            testPstmt1.addBatch();
            testPstmt1.setInt(1, 200);
            testPstmt1.addBatch();
            // One server-side prepared statement already prepared.
            int prepCount = 1;
            int expectedPrepCount = prepCount;
            int expectedExecCount = 0;
            int expectedCloseCount = 0;
            testBug80615CheckComStmtStatus(prepCount, true, testCase, checkStmt, expectedPrepCount, expectedExecCount, expectedCloseCount);
            // Prepare a number of statements higher than the limit set on server. There are at most (*) maxPrepStmtCount - 1 prepares available.
            // This should exhaust the number of allowed prepared statements, forcing the connector to use client-side prepared statements from that point
            // forward unless statements are closed correctly.
            // Under the tested circumstances there where some unexpected server prepared statements leaks (1st bug).
            // (*) There's no canonical way of knowing exactly how many preparing statement slots are available because other sessions may be using them.
            boolean isSPS = true;
            do {
                PreparedStatement testPstmt2 = testConn.prepareStatement("INSERT INTO testBug80615 VALUES (" + prepCount + " + ?)");
                prepCount++;
                isSPS = testPstmt2 instanceof ServerPreparedStatement;
                if (closeStmt) {
                    // Statements are being correctly closed so there is room to create new ones every time.
                    assertTrue(isSPS, testCase);
                } else if (prepCount > maxPrepStmtCount) {
                    // Not closing statements causes a server prepared statements leak on server.
                    // In this iteration (if not before) it should have started failing-over to a client-side prepared statement.
                    assertFalse(isSPS, testCase);
                } else if (prepCount <= prepStmtCacheSize + 2) {
                    // There should be enough room to prepare server-side prepared statements. (This was checked in the beginning.)
                    assertTrue(isSPS, testCase);
                }
                // prepStmtCacheSize + 1 < prepCount <= maxPrepStmtCount --> can't assert anything as there can statements prepared externally.
                // Need to cast, this is a JDBC 4.0 feature.
                ((StatementImpl) testPstmt2).setPoolable(poolable);
                testPstmt2.setInt(1, 0);
                testPstmt2.execute();
                if (isSPS) {
                    expectedPrepCount++;
                    expectedExecCount++;
                }
                if (closeStmt) {
                    testPstmt2.close();
                    if (isSPS) {
                        if (useCache && poolable && (prepCount - 1) > prepStmtCacheSize) {
                            // The first statement isn't cached yet.
                            // A statement (oldest in cache) is effectively closed on server side only after local statements cache is full.
                            expectedCloseCount++;
                        } else if (!useCache || !poolable) {
                            // The statement is closed immediately on server side.
                            expectedCloseCount++;
                        }
                    }
                }
                testBug80615CheckComStmtStatus(prepCount, isSPS, testCase, checkStmt, expectedPrepCount, expectedExecCount, expectedCloseCount);
            } while (prepCount < testRepetitions && isSPS);
            if (closeStmt) {
                assertEquals(testRepetitions, prepCount, testCase);
            } else {
                assertTrue(prepCount > prepStmtCacheSize + 2, testCase);
                assertTrue(prepCount <= maxPrepStmtCount + 1, testCase);
            }
            // Batched statements are being rewritten so this will prepare another statement underneath.
            // It was failing before if the the number of stmt prepares on server was exhausted at this point (2nd Bug).
            testPstmt1.executeBatch();
            testPstmt1.close();
            testConn.close();
        } while ((closeStmt = !closeStmt) || (useCache = !useCache) || (poolable = !poolable));
    } finally {
        if (maxPrepStmtCountOri >= 0) {
            this.stmt.execute("SET GLOBAL max_prepared_stmt_count = " + maxPrepStmtCountOri);
            this.stmt.execute("FLUSH STATUS");
        }
    }
}
Also used : JdbcStatement(com.mysql.cj.jdbc.JdbcStatement) JdbcPreparedStatement(com.mysql.cj.jdbc.JdbcPreparedStatement) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) ClientPreparedStatement(com.mysql.cj.jdbc.ClientPreparedStatement) StatementImpl(com.mysql.cj.jdbc.StatementImpl) ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) JdbcPreparedStatement(com.mysql.cj.jdbc.JdbcPreparedStatement) PreparedStatement(java.sql.PreparedStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) ClientPreparedStatement(com.mysql.cj.jdbc.ClientPreparedStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) Properties(java.util.Properties) StatementsTest(testsuite.simple.StatementsTest) Test(org.junit.jupiter.api.Test)

Example 2 with StatementImpl

use of com.mysql.cj.jdbc.StatementImpl in project JavaSegundasQuintas by ecteruel.

the class StatementRegressionTest method subTestBug68916ForDontTrackOpenResources.

private void subTestBug68916ForDontTrackOpenResources() throws Exception {
    Connection testConnection;
    String testStep;
    ResultSet testResultSet1, testResultSet2, testResultSet3;
    // We are testing against code that was compiled with Java 6, so methods isCloseOnCompletion() and
    // closeOnCompletion() aren't available in the Statement interface. We need to test directly our
    // implementations.
    StatementImpl testStatement = null;
    PreparedStatement testPrepStatement = null;
    CallableStatement testCallStatement = null;
    /*
         * Testing with connection property dontTrackOpenResources=true
         */
    testStep = "Conn. Prop. 'dontTrackOpenResources'";
    testConnection = getConnectionWithProps("dontTrackOpenResources=true");
    /*
         * SUB-STEP 0: The basics (dontTrackOpenResources=true)
         */
    // **testing Statement**
    // ResultSets should stay open when owning Statement is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    assertFalse(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): false by default.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.closeOnCompletion();
    assertTrue(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): true after Statement.closeOnCompletion().");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.closeOnCompletion();
    assertTrue(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): true after 2nd Statement.closeOnCompletion().");
    // test Statement.close()
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:0. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.close();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:0. ResultSet.isClosed(): false after Statement.Close().");
    assertTrue(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): true after Statement.Close().");
    // **testing PreparedStatement**
    // ResultSets should stay open when owning PreparedStatement is closed
    testPrepStatement = testConnection.prepareStatement("SELECT 1");
    assertFalse(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): false by default.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.closeOnCompletion();
    assertTrue(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): true after Statement.closeOnCompletion().");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.closeOnCompletion();
    assertTrue(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): true after 2nd Statement.closeOnCompletion().");
    // test PreparedStatement.close()
    testPrepStatement.execute();
    testResultSet1 = testPrepStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:0. ResultSet.isClosed(): false.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.close();
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:0. ResultSet.isClosed(): false after PreparedStatement.close().");
    assertTrue(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): true after PreparedStatement.close().");
    /*
         * SUB-STEP 1: One ResultSet (dontTrackOpenResources=true)
         */
    // **testing Statement**
    // Statement, although using closeOnCompletion, shouldn't be closed when last ResultSet is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    while (testResultSet1.next()) {
    }
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false when last ResultSet is closed.");
    // test implicit resultset (not) close, keeping statement open, when following with an executeBatch()
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    testStatement.addBatch("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)");
    testStatement.executeBatch();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false after executeBatch() in same Statement.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    testResultSet1 = testStatement.getGeneratedKeys();
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false when last ResultSet is closed.");
    // test implicit resultset (not) close keeping statement open, when following with an executeUpdate()
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)", Statement.RETURN_GENERATED_KEYS);
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false after executeUpdate() in same Statement.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    testResultSet1 = testStatement.getGeneratedKeys();
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false when last ResultSet is closed.");
    // **testing PreparedStatement**
    // PreparedStatement, although using closeOnCompletion, shouldn't be closed when last ResultSet is closed
    testPrepStatement = testConnection.prepareStatement("SELECT 1");
    testPrepStatement.closeOnCompletion();
    testResultSet1 = testPrepStatement.executeQuery();
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): false.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): false.");
    while (testResultSet1.next()) {
    }
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): false.");
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): true.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): false when last ResultSet is closed.");
    /*
         * SUB-STEP 2: Multiple ResultSets, sequentially (dontTrackOpenResources=true)
         */
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    // mustn't close testResultSet1
    testResultSet2 = testStatement.executeQuery("SELECT 2");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false after 2nd Statement.executeQuery().");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    while (testResultSet2.next()) {
    }
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    // mustn't close testResultSet1 nor testResultSet2
    testResultSet3 = testStatement.executeQuery("SELECT 3");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false after 3rd Statement.executeQuery().");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    testResultSet2.close();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    testResultSet1.close();
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet3.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false when last ResultSet is closed.");
    /*
         * SUB-STEP 3: Multiple ResultSets, returned at once (dontTrackOpenResources=true)
         */
    // **testing Statement**
    // Statement, although using closeOnCompletion, shouldn't be closed when last ResultSet is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    assertTrue(testStatement.execute("CALL testBug68916_proc"), testStep + ".ST:3. There should be some ResultSets.");
    testResultSet1 = testStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    assertTrue(testStatement.getMoreResults(Statement.KEEP_CURRENT_RESULT), testStep + ".ST:3. There should be more ResultSets.");
    testResultSet2 = testStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.KEEP_CURRENT_RESULT).");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    assertTrue(testStatement.getMoreResults(Statement.CLOSE_ALL_RESULTS), testStep + ".ST:3. There should be more ResultSets.");
    testResultSet3 = testStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    assertFalse(testStatement.getMoreResults(), testStep + ".ST:3. There should be no more ResultSets.");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false after last Satement.getMoreResults().");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false after last Satement.getMoreResults().");
    // since open ResultSets aren't tracked, we need to close all manually
    testResultSet1.close();
    testResultSet2.close();
    testResultSet3.close();
    // although there are no more ResultSets, Statement mustn't be closed
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false when last ResultSet is closed.");
    // **testing CallableStatement**
    // CallableStatement, although using closeOnCompletion, shouldn't be closed when last ResultSet is closed
    testCallStatement = testConnection.prepareCall("CALL testBug68916_proc");
    testCallStatement.closeOnCompletion();
    assertTrue(testCallStatement.execute(), testStep + ".CS:3. There should be some ResultSets.");
    testResultSet1 = testCallStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    assertTrue(testCallStatement.getMoreResults(Statement.KEEP_CURRENT_RESULT), testStep + ".CS:3. There should be more ResultSets.");
    testResultSet2 = testCallStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.KEEP_CURRENT_RESULT).");
    assertFalse(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    assertTrue(testCallStatement.getMoreResults(Statement.CLOSE_ALL_RESULTS), testStep + ".CS:3. There should be more ResultSets.");
    testResultSet3 = testCallStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet3.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    assertFalse(testCallStatement.getMoreResults(), testStep + ".CS:3. There should be no more ResultSets.");
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testResultSet3.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false after last Satement.getMoreResults().");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false after last Satement.getMoreResults().");
    // since open ResultSets aren't tracked, we need to close all manually
    testResultSet1.close();
    testResultSet2.close();
    testResultSet3.close();
    // although there are no more ResultSets, Statement mustn't be closed
    assertTrue(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false when last ResultSet is closed.");
    /*
         * SUB-STEP 4: Generated Keys ResultSet (dontTrackOpenResources=true)
         */
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)", Statement.RETURN_GENERATED_KEYS);
    testResultSet1 = testStatement.getGeneratedKeys();
    assertTrue(testResultSet1.next(), testStep + ".ST:4. Statement.getGeneratedKeys(): should return some values.");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false.");
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false when last ResultSet is closed.");
    // test again and combine with simple query
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (4), (5), (6)", Statement.RETURN_GENERATED_KEYS);
    testResultSet1 = testStatement.getGeneratedKeys();
    assertTrue(testResultSet1.next(), testStep + ".ST:4. Statement.getGeneratedKeys(): should return some values.");
    testResultSet2 = testStatement.executeQuery("SELECT 2");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false after executeQuery() in same Statement.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false.");
    testResultSet2.close();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false when last ResultSet is closed (still one open).");
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false when last ResultSet is closed.");
    testConnection.close();
}
Also used : CallableStatement(java.sql.CallableStatement) StatementImpl(com.mysql.cj.jdbc.StatementImpl) ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) ResultSet(java.sql.ResultSet) JdbcPreparedStatement(com.mysql.cj.jdbc.JdbcPreparedStatement) PreparedStatement(java.sql.PreparedStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) ClientPreparedStatement(com.mysql.cj.jdbc.ClientPreparedStatement)

Example 3 with StatementImpl

use of com.mysql.cj.jdbc.StatementImpl in project ABC by RuiPinto96274.

the class StatementRegressionTest method subTestBug68916ForDontTrackOpenResources.

private void subTestBug68916ForDontTrackOpenResources() throws Exception {
    Connection testConnection;
    String testStep;
    ResultSet testResultSet1, testResultSet2, testResultSet3;
    // We are testing against code that was compiled with Java 6, so methods isCloseOnCompletion() and
    // closeOnCompletion() aren't available in the Statement interface. We need to test directly our
    // implementations.
    StatementImpl testStatement = null;
    PreparedStatement testPrepStatement = null;
    CallableStatement testCallStatement = null;
    /*
         * Testing with connection property dontTrackOpenResources=true
         */
    testStep = "Conn. Prop. 'dontTrackOpenResources'";
    testConnection = getConnectionWithProps("dontTrackOpenResources=true");
    /*
         * SUB-STEP 0: The basics (dontTrackOpenResources=true)
         */
    // **testing Statement**
    // ResultSets should stay open when owning Statement is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    assertFalse(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): false by default.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.closeOnCompletion();
    assertTrue(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): true after Statement.closeOnCompletion().");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.closeOnCompletion();
    assertTrue(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): true after 2nd Statement.closeOnCompletion().");
    // test Statement.close()
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:0. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.close();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:0. ResultSet.isClosed(): false after Statement.Close().");
    assertTrue(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): true after Statement.Close().");
    // **testing PreparedStatement**
    // ResultSets should stay open when owning PreparedStatement is closed
    testPrepStatement = testConnection.prepareStatement("SELECT 1");
    assertFalse(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): false by default.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.closeOnCompletion();
    assertTrue(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): true after Statement.closeOnCompletion().");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.closeOnCompletion();
    assertTrue(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): true after 2nd Statement.closeOnCompletion().");
    // test PreparedStatement.close()
    testPrepStatement.execute();
    testResultSet1 = testPrepStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:0. ResultSet.isClosed(): false.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.close();
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:0. ResultSet.isClosed(): false after PreparedStatement.close().");
    assertTrue(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): true after PreparedStatement.close().");
    /*
         * SUB-STEP 1: One ResultSet (dontTrackOpenResources=true)
         */
    // **testing Statement**
    // Statement, although using closeOnCompletion, shouldn't be closed when last ResultSet is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    while (testResultSet1.next()) {
    }
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false when last ResultSet is closed.");
    // test implicit resultset (not) close, keeping statement open, when following with an executeBatch()
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    testStatement.addBatch("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)");
    testStatement.executeBatch();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false after executeBatch() in same Statement.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    testResultSet1 = testStatement.getGeneratedKeys();
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false when last ResultSet is closed.");
    // test implicit resultset (not) close keeping statement open, when following with an executeUpdate()
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)", Statement.RETURN_GENERATED_KEYS);
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false after executeUpdate() in same Statement.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    testResultSet1 = testStatement.getGeneratedKeys();
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false when last ResultSet is closed.");
    // **testing PreparedStatement**
    // PreparedStatement, although using closeOnCompletion, shouldn't be closed when last ResultSet is closed
    testPrepStatement = testConnection.prepareStatement("SELECT 1");
    testPrepStatement.closeOnCompletion();
    testResultSet1 = testPrepStatement.executeQuery();
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): false.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): false.");
    while (testResultSet1.next()) {
    }
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): false.");
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): true.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): false when last ResultSet is closed.");
    /*
         * SUB-STEP 2: Multiple ResultSets, sequentially (dontTrackOpenResources=true)
         */
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    // mustn't close testResultSet1
    testResultSet2 = testStatement.executeQuery("SELECT 2");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false after 2nd Statement.executeQuery().");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    while (testResultSet2.next()) {
    }
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    // mustn't close testResultSet1 nor testResultSet2
    testResultSet3 = testStatement.executeQuery("SELECT 3");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false after 3rd Statement.executeQuery().");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    testResultSet2.close();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    testResultSet1.close();
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet3.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false when last ResultSet is closed.");
    /*
         * SUB-STEP 3: Multiple ResultSets, returned at once (dontTrackOpenResources=true)
         */
    // **testing Statement**
    // Statement, although using closeOnCompletion, shouldn't be closed when last ResultSet is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    assertTrue(testStatement.execute("CALL testBug68916_proc"), testStep + ".ST:3. There should be some ResultSets.");
    testResultSet1 = testStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    assertTrue(testStatement.getMoreResults(Statement.KEEP_CURRENT_RESULT), testStep + ".ST:3. There should be more ResultSets.");
    testResultSet2 = testStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.KEEP_CURRENT_RESULT).");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    assertTrue(testStatement.getMoreResults(Statement.CLOSE_ALL_RESULTS), testStep + ".ST:3. There should be more ResultSets.");
    testResultSet3 = testStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    assertFalse(testStatement.getMoreResults(), testStep + ".ST:3. There should be no more ResultSets.");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false after last Satement.getMoreResults().");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false after last Satement.getMoreResults().");
    // since open ResultSets aren't tracked, we need to close all manually
    testResultSet1.close();
    testResultSet2.close();
    testResultSet3.close();
    // although there are no more ResultSets, Statement mustn't be closed
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false when last ResultSet is closed.");
    // **testing CallableStatement**
    // CallableStatement, although using closeOnCompletion, shouldn't be closed when last ResultSet is closed
    testCallStatement = testConnection.prepareCall("CALL testBug68916_proc");
    testCallStatement.closeOnCompletion();
    assertTrue(testCallStatement.execute(), testStep + ".CS:3. There should be some ResultSets.");
    testResultSet1 = testCallStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    assertTrue(testCallStatement.getMoreResults(Statement.KEEP_CURRENT_RESULT), testStep + ".CS:3. There should be more ResultSets.");
    testResultSet2 = testCallStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.KEEP_CURRENT_RESULT).");
    assertFalse(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    assertTrue(testCallStatement.getMoreResults(Statement.CLOSE_ALL_RESULTS), testStep + ".CS:3. There should be more ResultSets.");
    testResultSet3 = testCallStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet3.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    assertFalse(testCallStatement.getMoreResults(), testStep + ".CS:3. There should be no more ResultSets.");
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testResultSet3.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false after last Satement.getMoreResults().");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false after last Satement.getMoreResults().");
    // since open ResultSets aren't tracked, we need to close all manually
    testResultSet1.close();
    testResultSet2.close();
    testResultSet3.close();
    // although there are no more ResultSets, Statement mustn't be closed
    assertTrue(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false when last ResultSet is closed.");
    /*
         * SUB-STEP 4: Generated Keys ResultSet (dontTrackOpenResources=true)
         */
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)", Statement.RETURN_GENERATED_KEYS);
    testResultSet1 = testStatement.getGeneratedKeys();
    assertTrue(testResultSet1.next(), testStep + ".ST:4. Statement.getGeneratedKeys(): should return some values.");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false.");
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false when last ResultSet is closed.");
    // test again and combine with simple query
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (4), (5), (6)", Statement.RETURN_GENERATED_KEYS);
    testResultSet1 = testStatement.getGeneratedKeys();
    assertTrue(testResultSet1.next(), testStep + ".ST:4. Statement.getGeneratedKeys(): should return some values.");
    testResultSet2 = testStatement.executeQuery("SELECT 2");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false after executeQuery() in same Statement.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false.");
    testResultSet2.close();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false when last ResultSet is closed (still one open).");
    // although it's last open ResultSet, Statement mustn't be closed
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false when last ResultSet is closed.");
    testConnection.close();
}
Also used : CallableStatement(java.sql.CallableStatement) StatementImpl(com.mysql.cj.jdbc.StatementImpl) ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) ResultSet(java.sql.ResultSet) JdbcPreparedStatement(com.mysql.cj.jdbc.JdbcPreparedStatement) PreparedStatement(java.sql.PreparedStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) ClientPreparedStatement(com.mysql.cj.jdbc.ClientPreparedStatement)

Example 4 with StatementImpl

use of com.mysql.cj.jdbc.StatementImpl in project ABC by RuiPinto96274.

the class StatementRegressionTest method subTestBug68916ForAllowMultiQueries.

private void subTestBug68916ForAllowMultiQueries() throws Exception {
    Connection testConnection;
    String testStep;
    ResultSet testResultSet1, testResultSet2, testResultSet3;
    // We are testing against code that was compiled with Java 6, so methods isCloseOnCompletion() and
    // closeOnCompletion() aren't available in the Statement interface. We need to test directly our
    // implementations.
    StatementImpl testStatement = null;
    PreparedStatement testPrepStatement = null;
    CallableStatement testCallStatement = null;
    /*
         * Testing with connection property allowMultiQueries=true
         */
    testStep = "Conn. Prop. 'allowMultiQueries'";
    testConnection = getConnectionWithProps("allowMultiQueries=true");
    /*
         * SUB-STEP 0: The basics (allowMultiQueries=true)
         */
    // **testing Statement**
    // ResultSets should be closed when owning Statement is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    assertFalse(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): false by default.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.closeOnCompletion();
    assertTrue(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): true after Statement.closeOnCompletion().");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.closeOnCompletion();
    assertTrue(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): true after 2nd Statement.closeOnCompletion().");
    // test Statement.close()
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:0. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:0. ResultSet.isClosed(): true after Statement.Close().");
    assertTrue(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): true after Statement.Close().");
    // **testing PreparedStatement**
    // ResultSets should be closed when owning PreparedStatement is closed
    testPrepStatement = testConnection.prepareStatement("SELECT 1");
    assertFalse(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): false by default.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.closeOnCompletion();
    assertTrue(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): true after Statement.closeOnCompletion().");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.closeOnCompletion();
    assertTrue(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): true after 2nd Statement.closeOnCompletion().");
    // test PreparedStatement.close()
    testPrepStatement.execute();
    testResultSet1 = testPrepStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:0. ResultSet.isClosed(): false.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".PS:0. ResultSet.isClosed(): true after PreparedStatement.close().");
    assertTrue(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): true after PreparedStatement.close().");
    /*
         * SUB-STEP 1: One ResultSet (allowMultiQueries=true)
         */
    // **testing Statement**
    // Statement using closeOnCompletion should be closed when last ResultSet is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    while (testResultSet1.next()) {
    }
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    // last open ResultSet, must close Statement
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): true when last ResultSet is closed.");
    // test implicit resultset close, keeping statement open, when following with an executeBatch()
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    testStatement.addBatch("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)");
    testStatement.executeBatch();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true after executeBatch() in same Statement.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    testResultSet1 = testStatement.getGeneratedKeys();
    // last open ResultSet, must close Statement
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): true when last ResultSet is closed.");
    // test implicit resultset close keeping statement open, when following with an executeUpdate()
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)", Statement.RETURN_GENERATED_KEYS);
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true after executeUpdate() in same Statement.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    testResultSet1 = testStatement.getGeneratedKeys();
    // last open ResultSet, must close Statement
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): true when last ResultSet is closed.");
    // **testing PreparedStatement**
    // PreparedStatement using closeOnCompletion should be closed when last ResultSet is closed
    testPrepStatement = testConnection.prepareStatement("SELECT 1");
    testPrepStatement.closeOnCompletion();
    testResultSet1 = testPrepStatement.executeQuery();
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): false.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): false.");
    while (testResultSet1.next()) {
    }
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): false.");
    // last open ResultSet, must close Statement
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): true.");
    assertTrue(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): true when last ResultSet is closed.");
    /*
         * SUB-STEP 2: Multiple ResultSets, sequentially (allowMultiQueries=true)
         */
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    // closes testResultSet1
    testResultSet2 = testStatement.executeQuery("SELECT 2; SELECT 3");
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true after 2nd Statement.executeQuery().");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    while (testResultSet2.next()) {
    }
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    // closes
    assertTrue(testStatement.getMoreResults(), testStep + ".ST:3. There should be more ResultSets.");
    // testResultSet2
    testResultSet3 = testStatement.getResultSet();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true after Statement.getMoreResults().");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    // last open ResultSet, must close Statement
    testResultSet3.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): true when last ResultSet is closed.");
    /*
         * SUB-STEP 3: Multiple ResultSets, returned at once (allowMultiQueries=true)
         */
    // **testing Statement**
    // Statement using closeOnCompletion should be closed when last ResultSet is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1; SELECT 2; SELECT 3");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    assertTrue(testStatement.getMoreResults(Statement.KEEP_CURRENT_RESULT), testStep + ".ST:3. There should be more ResultSets.");
    testResultSet2 = testStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.KEEP_CURRENT_RESULT).");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    assertTrue(testStatement.getMoreResults(Statement.CLOSE_ALL_RESULTS), testStep + ".ST:3. There should be more ResultSets.");
    testResultSet3 = testStatement.getResultSet();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    // no more ResultSets, must close Statement
    assertFalse(testStatement.getMoreResults(), testStep + ".ST:3. There should be no more ResultSets.");
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true after last Satement.getMoreResults().");
    assertTrue(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): true when last ResultSet is closed.");
    // **testing CallableStatement**
    // CallableStatement using closeOnCompletion should be closed when last ResultSet is closed
    testCallStatement = testConnection.prepareCall("CALL testBug68916_proc");
    testCallStatement.closeOnCompletion();
    assertTrue(testCallStatement.execute(), testStep + ".CS:3. There should be some ResultSets.");
    testResultSet1 = testCallStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    assertTrue(testCallStatement.getMoreResults(Statement.KEEP_CURRENT_RESULT), testStep + ".CS:3. There should be more ResultSets.");
    testResultSet2 = testCallStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.KEEP_CURRENT_RESULT).");
    assertFalse(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    assertTrue(testCallStatement.getMoreResults(Statement.CLOSE_ALL_RESULTS), testStep + ".CS:3. There should be more ResultSets.");
    testResultSet3 = testCallStatement.getResultSet();
    assertTrue(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertTrue(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet3.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    // no more ResultSets, must close Statement
    assertFalse(testCallStatement.getMoreResults(), testStep + ".CS:3. There should be no more ResultSets.");
    assertTrue(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true after last Satement.getMoreResults().");
    assertTrue(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): true when last ResultSet is closed.");
    /*
         * SUB-STEP 4: Generated Keys ResultSet (allowMultiQueries=true)
         */
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3); INSERT INTO testBug68916_tbl (fld2) VALUES (4), (5), (6)", Statement.RETURN_GENERATED_KEYS);
    testResultSet1 = testStatement.getGeneratedKeys();
    assertTrue(testResultSet1.next(), testStep + ".ST:4. Statement.getGeneratedKeys(): should return some values.");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false.");
    // last open ResultSet, must close Statement
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): true when last ResultSet is closed.");
    // test again and combine with simple query
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (4), (5), (6)", Statement.RETURN_GENERATED_KEYS);
    testResultSet1 = testStatement.getGeneratedKeys();
    assertTrue(testResultSet1.next(), testStep + ".ST:4. Statement.getGeneratedKeys(): should return some values.");
    testResultSet2 = testStatement.executeQuery("SELECT 2; SELECT 3");
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true after executeQuery() in same Statement.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false.");
    // last open ResultSet won't close the Statement
    // because we didn't fetch the next one (SELECT 3)
    testResultSet2.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): true when last ResultSet is closed.");
    testStatement.close();
    testConnection.close();
}
Also used : CallableStatement(java.sql.CallableStatement) StatementImpl(com.mysql.cj.jdbc.StatementImpl) ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) ResultSet(java.sql.ResultSet) JdbcPreparedStatement(com.mysql.cj.jdbc.JdbcPreparedStatement) PreparedStatement(java.sql.PreparedStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) ClientPreparedStatement(com.mysql.cj.jdbc.ClientPreparedStatement)

Example 5 with StatementImpl

use of com.mysql.cj.jdbc.StatementImpl in project ABC by RuiPinto96274.

the class StatementRegressionTest method subTestBug68916ForStandardConnection.

private void subTestBug68916ForStandardConnection() throws Exception {
    Connection testConnection = this.conn;
    String testStep;
    ResultSet testResultSet1, testResultSet2, testResultSet3;
    // We are testing against code that was compiled with Java 6, so methods isCloseOnCompletion() and
    // closeOnCompletion() aren't available in the Statement interface. We need to test directly our implementations.
    StatementImpl testStatement = null;
    PreparedStatement testPrepStatement = null;
    CallableStatement testCallStatement = null;
    /*
         * Testing with standard connection (no properties)
         */
    testStep = "Standard Connection";
    /*
         * SUB-STEP 0: The basics (connection without properties)
         */
    // **testing Statement**
    // ResultSets should be closed when owning Statement is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    assertFalse(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): false by default.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.closeOnCompletion();
    assertTrue(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): true after Statement.closeOnCompletion().");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.closeOnCompletion();
    assertTrue(testStatement.isCloseOnCompletion(), testStep + ".ST:0. Statement.isCloseOnCompletion(): true after 2nd Statement.closeOnCompletion().");
    // test Statement.close()
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:0. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): false.");
    testStatement.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:0. ResultSet.isClosed(): true after Statement.Close().");
    assertTrue(testStatement.isClosed(), testStep + ".ST:0. Statement.isClosed(): true after Statement.Close().");
    // **testing PreparedStatement**
    // ResultSets should be closed when owning PreparedStatement is closed
    testPrepStatement = testConnection.prepareStatement("SELECT 1");
    assertFalse(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): false by default.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.closeOnCompletion();
    assertTrue(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): true after Statement.closeOnCompletion().");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.closeOnCompletion();
    assertTrue(testPrepStatement.isCloseOnCompletion(), testStep + ".PS:0. PreparedStatement.isCloseOnCompletion(): true after 2nd Statement.closeOnCompletion().");
    // test PreparedStatement.close()
    testPrepStatement.execute();
    testResultSet1 = testPrepStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:0. ResultSet.isClosed(): false.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): false.");
    testPrepStatement.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".PS:0. ResultSet.isClosed(): true after PreparedStatement.close().");
    assertTrue(testPrepStatement.isClosed(), testStep + ".PS:0. PreparedStatement.isClosed(): true after PreparedStatement.close().");
    /*
         * SUB-STEP 1: One ResultSet (connection without properties)
         */
    // **testing Statement**
    // Statement using closeOnCompletion should be closed when last ResultSet is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    while (testResultSet1.next()) {
    }
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    // last open ResultSet, must close Statement
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): true when last ResultSet is closed.");
    // test implicit resultset close, keeping statement open, when following with an executeBatch()
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    testStatement.addBatch("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)");
    testStatement.executeBatch();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true after executeBatch() in same Statement.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    testResultSet1 = testStatement.getGeneratedKeys();
    // last open ResultSet, must close Statement
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): true when last ResultSet is closed.");
    // test implicit resultset close keeping statement open, when following with an executeUpdate()
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)", Statement.RETURN_GENERATED_KEYS);
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true after executeUpdate() in same Statement.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): false.");
    testResultSet1 = testStatement.getGeneratedKeys();
    // last open ResultSet, must close Statement
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:1. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:1. Statement.isClosed(): true when last ResultSet is closed.");
    // **testing PreparedStatement**
    // PreparedStatement using closeOnCompletion should be closed when last ResultSet is closed
    testPrepStatement = testConnection.prepareStatement("SELECT 1");
    testPrepStatement.closeOnCompletion();
    testResultSet1 = testPrepStatement.executeQuery();
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): false.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): false.");
    while (testResultSet1.next()) {
    }
    assertFalse(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): false.");
    // last open ResultSet, must close Statement
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".PS:1. ResultSet.isClosed(): true.");
    assertTrue(testPrepStatement.isClosed(), testStep + ".PS:1. PreparedStatement.isClosed(): true when last ResultSet is closed.");
    /*
         * SUB-STEP 2: Multiple ResultSets, sequentially (connection without properties)
         */
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testResultSet1 = testStatement.executeQuery("SELECT 1");
    // closes testResultSet1
    testResultSet2 = testStatement.executeQuery("SELECT 2");
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true after 2nd Statement.executeQuery().");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    while (testResultSet2.next()) {
    }
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false after ResultSet have reached the end.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    // closes testResultSet2
    testResultSet3 = testStatement.executeQuery("SELECT 3");
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true after 3rd Statement.executeQuery().");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): false.");
    // last open ResultSet, must close Statement
    testResultSet3.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".ST:2. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:2. Statement.isClosed(): true when last ResultSet is closed.");
    /*
         * SUB-STEP 3: Multiple ResultSets, returned at once (connection without properties)
         */
    // **testing Statement**
    // Statement using closeOnCompletion should be closed when last ResultSet is closed
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    assertTrue(testStatement.execute("CALL testBug68916_proc"), testStep + ".ST:3. There should be some ResultSets.");
    testResultSet1 = testStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    assertTrue(testStatement.getMoreResults(Statement.KEEP_CURRENT_RESULT), testStep + ".ST:3. There should be more ResultSets.");
    testResultSet2 = testStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.KEEP_CURRENT_RESULT).");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    assertTrue(testStatement.getMoreResults(Statement.CLOSE_ALL_RESULTS), testStep + ".ST:3. There should be more ResultSets.");
    testResultSet3 = testStatement.getResultSet();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet3.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): false.");
    // no more ResultSets, must close Statement
    assertFalse(testStatement.getMoreResults(), testStep + ".ST:3. There should be no more ResultSets.");
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".ST:3. ResultSet.isClosed(): true after last Satement.getMoreResults().");
    assertTrue(testStatement.isClosed(), testStep + ".ST:3. Statement.isClosed(): true when last ResultSet is closed.");
    // **testing CallableStatement**
    // CallableStatement using closeOnCompletion should be closed when last ResultSet is closed
    testCallStatement = testConnection.prepareCall("CALL testBug68916_proc");
    testCallStatement.closeOnCompletion();
    assertTrue(testCallStatement.execute(), testStep + ".CS:3. There should be some ResultSets.");
    testResultSet1 = testCallStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    assertTrue(testCallStatement.getMoreResults(Statement.KEEP_CURRENT_RESULT), testStep + ".CS:3. There should be more ResultSets.");
    testResultSet2 = testCallStatement.getResultSet();
    assertFalse(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false after Statement.getMoreResults(Statement.KEEP_CURRENT_RESULT).");
    assertFalse(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    assertTrue(testCallStatement.getMoreResults(Statement.CLOSE_ALL_RESULTS), testStep + ".CS:3. There should be more ResultSets.");
    testResultSet3 = testCallStatement.getResultSet();
    assertTrue(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertTrue(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true after Statement.getMoreResults(Statement.CLOSE_ALL_RESULTS).");
    assertFalse(testResultSet3.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): false.");
    assertFalse(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): false.");
    // no more ResultSets, must close Statement
    assertFalse(testCallStatement.getMoreResults(), testStep + ".CS:3. There should be no more ResultSets.");
    assertTrue(testResultSet1.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true.");
    assertTrue(testResultSet3.isClosed(), testStep + ".CS:3. ResultSet.isClosed(): true after last Satement.getMoreResults().");
    assertTrue(testCallStatement.isClosed(), testStep + ".CS:3. CallableStatement.isClosed(): true when last ResultSet is closed.");
    /*
         * SUB-STEP 4: Generated Keys ResultSet (connection without properties)
         */
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (1), (2), (3)", Statement.RETURN_GENERATED_KEYS);
    testResultSet1 = testStatement.getGeneratedKeys();
    assertTrue(testResultSet1.next(), testStep + ".ST:4. Statement.getGeneratedKeys(): should return some values.");
    assertFalse(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false.");
    // last open ResultSet, must close Statement
    testResultSet1.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): true when last ResultSet is closed.");
    // test again and combine with simple query
    testStatement = (StatementImpl) testConnection.createStatement();
    testStatement.closeOnCompletion();
    testStatement.executeUpdate("INSERT INTO testBug68916_tbl (fld2) VALUES (4), (5), (6)", Statement.RETURN_GENERATED_KEYS);
    testResultSet1 = testStatement.getGeneratedKeys();
    assertTrue(testResultSet1.next(), testStep + ".ST:4. Statement.getGeneratedKeys(): should return some values.");
    testResultSet2 = testStatement.executeQuery("SELECT 2");
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true after executeQuery() in same Statement.");
    assertFalse(testResultSet2.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): false.");
    assertFalse(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): false.");
    // last open ResultSet, must close Statement
    testResultSet2.close();
    assertTrue(testResultSet1.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertTrue(testResultSet2.isClosed(), testStep + ".ST:4. ResultSet.isClosed(): true.");
    assertTrue(testStatement.isClosed(), testStep + ".ST:4. Statement.isClosed(): true when last ResultSet is closed.");
}
Also used : CallableStatement(java.sql.CallableStatement) StatementImpl(com.mysql.cj.jdbc.StatementImpl) ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) ResultSet(java.sql.ResultSet) JdbcPreparedStatement(com.mysql.cj.jdbc.JdbcPreparedStatement) PreparedStatement(java.sql.PreparedStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) ClientPreparedStatement(com.mysql.cj.jdbc.ClientPreparedStatement)

Aggregations

StatementImpl (com.mysql.cj.jdbc.StatementImpl)21 MysqlConnection (com.mysql.cj.MysqlConnection)18 JdbcConnection (com.mysql.cj.jdbc.JdbcConnection)18 ServerPreparedStatement (com.mysql.cj.jdbc.ServerPreparedStatement)18 CallableStatement (java.sql.CallableStatement)18 Connection (java.sql.Connection)18 PreparedStatement (java.sql.PreparedStatement)18 ClientPreparedStatement (com.mysql.cj.jdbc.ClientPreparedStatement)15 JdbcPreparedStatement (com.mysql.cj.jdbc.JdbcPreparedStatement)15 ReplicationConnection (com.mysql.cj.jdbc.ha.ReplicationConnection)15 ResultSet (java.sql.ResultSet)15 XAConnection (javax.sql.XAConnection)15 Statement (java.sql.Statement)6 Properties (java.util.Properties)6 Test (org.junit.jupiter.api.Test)6 ExceptionInterceptor (com.mysql.cj.exceptions.ExceptionInterceptor)3 ExceptionInterceptorChain (com.mysql.cj.exceptions.ExceptionInterceptorChain)3 JdbcStatement (com.mysql.cj.jdbc.JdbcStatement)3 UpdatableResultSet (com.mysql.cj.jdbc.result.UpdatableResultSet)3 ResultsetRowsCursor (com.mysql.cj.protocol.a.result.ResultsetRowsCursor)3