Search in sources :

Example 1 with ServerPreparedStatement

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

the class ResultSetRegressionTest method testBug31747910.

/**
 * Tests fix for Bug#31747910, BUG 30474158 FIX IMPROVES JDBC COMPLIANCE BUT CHANGES DEFAULT RESULTSETTYPE HANDLING.
 *
 * @throws Exception
 */
@Test
public void testBug31747910() throws Exception {
    createTable("testBug31747910", "(id INT)");
    this.stmt.executeUpdate("INSERT INTO testBug31747910 VALUES (1), (2), (3), (4), (5)");
    /*
         * Expected exceptions with default RS type and:
         * 0. static;
         * 1. streaming;
         * 2. streaming & scroll-tolerant;
         * 3. cursor-based;
         * 4. cursor-based & scroll-tolerant.
         */
    String[] connOpts = new String[] { "useSSL=false,allowPublicKeyRetrieval=true", "useSSL=false,allowPublicKeyRetrieval=true", "useSSL=false,allowPublicKeyRetrieval=true,scrollTolerantForwardOnly=true", "useSSL=false,allowPublicKeyRetrieval=true,useCursorFetch=true", "useSSL=false,allowPublicKeyRetrieval=true,useCursorFetch=true,scrollTolerantForwardOnly=true" };
    int[] fetchSize = new int[] { 0, Integer.MIN_VALUE, Integer.MIN_VALUE, 2, 2 };
    for (int i = 0; i < connOpts.length; i++) {
        for (int j = 0; j < 3; j++) {
            // Statement; PreparedStatement and ServerPreparedStatement.
            Connection testConn = null;
            Statement testStmt = null;
            switch(j) {
                case 0:
                    // Default behavior using Statement
                    testConn = getConnectionWithProps(connOpts[i]);
                    testStmt = testConn.createStatement();
                    if (fetchSize[i] != 0) {
                        testStmt.setFetchSize(fetchSize[i]);
                    }
                    this.rs = testStmt.executeQuery("SELECT * FROM testBug31747910");
                    break;
                case 1:
                    // Default behavior using PreparedStatement
                    testConn = getConnectionWithProps(connOpts[i]);
                    testStmt = testConn.prepareStatement("SELECT * FROM testBug31747910");
                    if (fetchSize[i] != 0) {
                        testStmt.setFetchSize(fetchSize[i]);
                    }
                    this.rs = ((PreparedStatement) testStmt).executeQuery();
                    break;
                case 2:
                    // Default behavior using ServerPreparedStatement
                    testConn = getConnectionWithProps("useServerPrepStmts=true," + connOpts[i]);
                    testStmt = testConn.prepareStatement("SELECT * FROM testBug31747910");
                    if (fetchSize[i] != 0) {
                        testStmt.setFetchSize(fetchSize[i]);
                    }
                    this.rs = ((PreparedStatement) testStmt).executeQuery();
                    break;
            }
            assertTrue(this.rs.next());
            assertEquals(1, this.rs.getInt(1));
            assertThrows(SQLException.class, "Operation not allowed for a result set of type ResultSet\\.TYPE_FORWARD_ONLY\\.", () -> this.rs.last());
            assertThrows(SQLException.class, "Operation not allowed for a result set of type ResultSet\\.TYPE_FORWARD_ONLY\\.", () -> this.rs.previous());
            assertThrows(SQLException.class, "Operation not allowed for a result set of type ResultSet\\.TYPE_FORWARD_ONLY\\.", () -> this.rs.first());
            assertThrows(SQLException.class, "Operation not allowed for a result set of type ResultSet\\.TYPE_FORWARD_ONLY\\.", () -> this.rs.absolute(3));
            assertThrows(SQLException.class, "Operation not allowed for a result set of type ResultSet\\.TYPE_FORWARD_ONLY\\.", () -> this.rs.relative(-1));
            assertThrows(SQLException.class, "Operation not allowed for a result set of type ResultSet\\.TYPE_FORWARD_ONLY\\.", () -> {
                this.rs.beforeFirst();
                return null;
            });
            assertThrows(SQLException.class, "Operation not allowed for a result set of type ResultSet\\.TYPE_FORWARD_ONLY\\.", () -> {
                this.rs.afterLast();
                return null;
            });
            testStmt.close();
            testConn.close();
        }
    }
    // Scroll-tolerant behavior using: Statement; PreparedStatement; ServerPreparedStatement.
    for (int i = 0; i < 3; i++) {
        Connection testConn = null;
        Statement testStmt = null;
        switch(i) {
            case 0:
                // Scroll-tolerant using Statement
                testConn = getConnectionWithProps("useSSL=false,allowPublicKeyRetrieval=true,scrollTolerantForwardOnly=true");
                testStmt = testConn.createStatement();
                this.rs = testStmt.executeQuery("SELECT * FROM testBug31747910");
                break;
            case 1:
                // Scroll-tolerant using PreparedStatement
                testConn = getConnectionWithProps("useSSL=false,allowPublicKeyRetrieval=true,scrollTolerantForwardOnly=true");
                testStmt = testConn.prepareStatement("SELECT * FROM testBug31747910");
                this.rs = ((PreparedStatement) testStmt).executeQuery();
                break;
            case 2:
                // Scroll-tolerant using ServerPreparedStatement
                testConn = getConnectionWithProps("useSSL=false,allowPublicKeyRetrieval=true,useServerPrepStmts=true,scrollTolerantForwardOnly=true");
                testStmt = testConn.prepareStatement("SELECT * FROM testBug31747910");
                this.rs = ((PreparedStatement) testStmt).executeQuery();
                break;
        }
        assertTrue(this.rs.next());
        assertEquals(1, this.rs.getInt(1));
        assertTrue(this.rs.last());
        assertEquals(5, this.rs.getInt(1));
        assertTrue(this.rs.previous());
        assertEquals(4, this.rs.getInt(1));
        assertTrue(this.rs.first());
        assertEquals(1, this.rs.getInt(1));
        assertTrue(this.rs.absolute(3));
        assertEquals(3, this.rs.getInt(1));
        assertTrue(this.rs.relative(-1));
        assertEquals(2, this.rs.getInt(1));
        this.rs.beforeFirst();
        assertTrue(this.rs.isBeforeFirst());
        this.rs.afterLast();
        assertTrue(this.rs.isAfterLast());
        testStmt.close();
        testConn.close();
    }
}
Also used : PreparedStatement(java.sql.PreparedStatement) CallableStatement(java.sql.CallableStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) Statement(java.sql.Statement) Connection(java.sql.Connection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) Test(org.junit.jupiter.api.Test)

Example 2 with ServerPreparedStatement

use of com.mysql.cj.jdbc.ServerPreparedStatement 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 3 with ServerPreparedStatement

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

the class StatementRegressionTest method testBug66430.

/**
 * Tests fix for Bug#66430 - setCatalog on connection leaves ServerPreparedStatement cache for old catalog.
 *
 * @throws Exception
 */
@Test
public void testBug66430() throws Exception {
    createDatabase("testBug66430DB1");
    createTable("testBug66430DB1.testBug66430", "(id INT)");
    this.stmt.executeUpdate("INSERT INTO testBug66430DB1.testBug66430 VALUES (1)");
    createDatabase("testBug66430DB2");
    createTable("testBug66430DB2.testBug66430", "(id INT)");
    this.stmt.executeUpdate("INSERT INTO testBug66430DB2.testBug66430 VALUES (2)");
    boolean useSPS = false;
    boolean cachePS = false;
    do {
        final String testCase = String.format("Case: [useSPS: %s, cachePS: %s ]", useSPS ? "Y" : "N", cachePS ? "Y" : "N");
        Properties props = new Properties();
        props.setProperty(PropertyKey.useSSL.getKeyName(), "false");
        props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        props.setProperty(PropertyKey.cachePrepStmts.getKeyName(), Boolean.toString(cachePS));
        props.setProperty(PropertyKey.useServerPrepStmts.getKeyName(), Boolean.toString(useSPS));
        Connection testConn = getConnectionWithProps(props);
        if (((JdbcConnection) testConn).getPropertySet().<DatabaseTerm>getEnumProperty(PropertyKey.databaseTerm).getValue() == DatabaseTerm.SCHEMA) {
            testConn.setSchema("testBug66430DB1");
        } else {
            testConn.setCatalog("testBug66430DB1");
        }
        PreparedStatement testPStmt = testConn.prepareStatement("SELECT * FROM testBug66430 WHERE id > ?");
        testPStmt.setInt(1, 0);
        this.rs = testPStmt.executeQuery();
        assertTrue(this.rs.next(), testCase);
        assertEquals(1, this.rs.getInt(1), testCase);
        assertFalse(this.rs.next(), testCase);
        testPStmt.close();
        if (((JdbcConnection) testConn).getPropertySet().<DatabaseTerm>getEnumProperty(PropertyKey.databaseTerm).getValue() == DatabaseTerm.SCHEMA) {
            testConn.setSchema("testBug66430DB2");
        } else {
            testConn.setCatalog("testBug66430DB2");
        }
        testPStmt = testConn.prepareStatement("SELECT * FROM testBug66430 WHERE id > ?");
        testPStmt.setInt(1, 0);
        this.rs = testPStmt.executeQuery();
        assertTrue(this.rs.next(), testCase);
        assertEquals(2, this.rs.getInt(1), testCase);
        assertFalse(this.rs.next(), testCase);
        testPStmt.close();
        // Do it again to make sure cached prepared statements behave correctly.
        if (((JdbcConnection) testConn).getPropertySet().<DatabaseTerm>getEnumProperty(PropertyKey.databaseTerm).getValue() == DatabaseTerm.SCHEMA) {
            testConn.setSchema("testBug66430DB1");
        } else {
            testConn.setCatalog("testBug66430DB1");
        }
        testPStmt = testConn.prepareStatement("SELECT * FROM testBug66430 WHERE id > ?");
        testPStmt.setInt(1, 0);
        this.rs = testPStmt.executeQuery();
        assertTrue(this.rs.next(), testCase);
        assertEquals(1, this.rs.getInt(1), testCase);
        assertFalse(this.rs.next(), testCase);
        testPStmt.close();
        if (((JdbcConnection) testConn).getPropertySet().<DatabaseTerm>getEnumProperty(PropertyKey.databaseTerm).getValue() == DatabaseTerm.SCHEMA) {
            testConn.setSchema("testBug66430DB2");
        } else {
            testConn.setCatalog("testBug66430DB2");
        }
        testPStmt = testConn.prepareStatement("SELECT * FROM testBug66430 WHERE id > ?");
        testPStmt.setInt(1, 0);
        this.rs = testPStmt.executeQuery();
        assertTrue(this.rs.next(), testCase);
        assertEquals(2, this.rs.getInt(1), testCase);
        assertFalse(this.rs.next(), testCase);
        testPStmt.close();
        testConn.close();
    } while ((useSPS = !useSPS) || (cachePS = !cachePS));
}
Also used : DatabaseTerm(com.mysql.cj.conf.PropertyDefinitions.DatabaseTerm) 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) Properties(java.util.Properties) StatementsTest(testsuite.simple.StatementsTest) Test(org.junit.jupiter.api.Test)

Example 4 with ServerPreparedStatement

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

the class StatementRegressionTest method testBug87429.

/**
 * Tests fix for Bug#87429 - repeated close of ServerPreparedStatement causes memory leak.
 *
 * Original de-cache on double close() behavior modified by:
 * WL#11101 - Remove de-cache and close of SSPSs on double call to close().
 *
 * @throws Exception
 */
@Test
public void testBug87429() throws Exception {
    Field stmtsCacheField = ConnectionImpl.class.getDeclaredField("serverSideStatementCache");
    stmtsCacheField.setAccessible(true);
    ToIntFunction<Connection> getStmtsCacheSize = (c) -> {
        try {
            LRUCache<?, ?> stmtsCacheObj = (LRUCache<?, ?>) stmtsCacheField.get(c);
            return stmtsCacheObj == null ? -1 : stmtsCacheObj.size();
        } catch (IllegalArgumentException | IllegalAccessException e) {
            fail("Fail getting the statemets cache size.");
            return -1;
        }
    };
    final String sql1 = "SELECT 1, ?";
    final String sql2 = "SELECT 2, ?";
    boolean useSPS = false;
    boolean cachePS = false;
    do {
        Properties props = new Properties();
        props.setProperty(PropertyKey.useSSL.getKeyName(), "false");
        props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        props.setProperty(PropertyKey.useServerPrepStmts.getKeyName(), Boolean.toString(useSPS));
        props.setProperty(PropertyKey.cachePrepStmts.getKeyName(), Boolean.toString(cachePS));
        props.setProperty(PropertyKey.prepStmtCacheSize.getKeyName(), "5");
        boolean cachedSPS = useSPS && cachePS;
        JdbcConnection testConn = (JdbcConnection) getConnectionWithProps(props);
        // Single PreparedStatement, closed multiple times.
        for (int i = 0; i < 100; i++) {
            this.pstmt = testConn.prepareStatement(sql1);
            assertTrue(this.pstmt.isPoolable());
            assertEquals(1, testConn.getActiveStatementCount());
            assertEquals(cachedSPS ? 0 : -1, getStmtsCacheSize.applyAsInt(testConn));
            // Close & cache.
            this.pstmt.close();
            assertEquals(cachedSPS ? 1 : 0, testConn.getActiveStatementCount());
            assertEquals(cachedSPS ? 1 : -1, getStmtsCacheSize.applyAsInt(testConn));
            // No-op.
            this.pstmt.close();
            assertEquals(cachedSPS ? 1 : 0, testConn.getActiveStatementCount());
            assertEquals(cachedSPS ? 1 : -1, getStmtsCacheSize.applyAsInt(testConn));
            // No-op.
            this.pstmt.close();
            assertEquals(cachedSPS ? 1 : 0, testConn.getActiveStatementCount());
            assertEquals(cachedSPS ? 1 : -1, getStmtsCacheSize.applyAsInt(testConn));
            try {
                // De-caches the statement or no-op if not cached.
                this.pstmt.setPoolable(false);
            } catch (SQLException e) {
                assertFalse(cachedSPS, "Exception [" + e.getMessage() + "] not expected.");
            }
            // No-op.
            this.pstmt.close();
            assertEquals(0, testConn.getActiveStatementCount());
            assertEquals(cachedSPS ? 0 : -1, getStmtsCacheSize.applyAsInt(testConn));
        }
        testConn.close();
        assertEquals(0, testConn.getActiveStatementCount());
        assertEquals(cachedSPS ? 0 : -1, getStmtsCacheSize.applyAsInt(testConn));
        testConn = (JdbcConnection) getConnectionWithProps(props);
        // Multiple PreparedStatements interchanged, two queries, closed multiple times.
        for (int i = 0; i < 100; i++) {
            for (int j = 1; j <= 4; j++) {
                PreparedStatement pstmt1 = testConn.prepareStatement(j == 1 ? sql2 : sql1);
                PreparedStatement pstmt2 = testConn.prepareStatement(j == 2 ? sql2 : sql1);
                PreparedStatement pstmt3 = testConn.prepareStatement(j == 3 ? sql2 : sql1);
                PreparedStatement pstmt4 = testConn.prepareStatement(j == 4 ? sql2 : sql1);
                assertEquals(4, testConn.getActiveStatementCount());
                // Close and cache statements successively.
                pstmt4.close();
                // No-op.
                pstmt4.close();
                assertEquals(cachedSPS ? 4 : 3, testConn.getActiveStatementCount());
                pstmt3.close();
                // No-op.
                pstmt3.close();
                assertEquals(cachedSPS ? (j >= 3 ? 4 : 3) : 2, testConn.getActiveStatementCount());
                pstmt2.close();
                // No-op.
                pstmt2.close();
                assertEquals(cachedSPS ? (j >= 2 ? 3 : 2) : 1, testConn.getActiveStatementCount());
                pstmt1.close();
                // No-op.
                pstmt1.close();
                assertEquals(cachedSPS ? 2 : 0, testConn.getActiveStatementCount());
                // No-ops.
                pstmt4.close();
                pstmt4.close();
                pstmt3.close();
                pstmt3.close();
                pstmt2.close();
                pstmt2.close();
                pstmt1.close();
                pstmt1.close();
                assertEquals(cachedSPS ? 2 : 0, testConn.getActiveStatementCount());
                // De-cache statements successively.
                try {
                    // De-caches the statement or no-op if not cached.
                    pstmt4.setPoolable(false);
                } catch (SQLException e) {
                    assertFalse(cachedSPS && j == 4, "Exception [" + e.getMessage() + "] not expected.");
                }
                // No-op.
                pstmt4.close();
                assertEquals(cachedSPS ? (j < 4 ? 2 : 1) : 0, testConn.getActiveStatementCount());
                try {
                    // De-caches the statement or no-op if not cached.
                    pstmt3.setPoolable(false);
                } catch (SQLException e) {
                    assertFalse(cachedSPS && j == 3, "Exception [" + e.getMessage() + "] not expected.");
                }
                // No-op.
                pstmt3.close();
                assertEquals(cachedSPS ? (j < 3 ? 2 : 1) : 0, testConn.getActiveStatementCount());
                try {
                    // De-caches the statement or no-op if not cached.
                    pstmt2.setPoolable(false);
                } catch (SQLException e) {
                    assertFalse(cachedSPS && j == 2, "Exception [" + e.getMessage() + "] not expected.");
                }
                // No-op.
                pstmt2.close();
                assertEquals(cachedSPS ? 1 : 0, testConn.getActiveStatementCount());
                try {
                    // De-caches the statement or no-op if not cached.
                    pstmt1.setPoolable(false);
                } catch (SQLException e) {
                    assertFalse(cachedSPS, "Exception [" + e.getMessage() + "] not expected.");
                }
                // No-op.
                pstmt1.close();
                assertEquals(0, testConn.getActiveStatementCount());
            }
        }
        testConn.close();
        assertEquals(0, testConn.getActiveStatementCount());
    } while ((useSPS = !useSPS) || (cachePS = !cachePS));
}
Also used : Arrays(java.util.Arrays) BaseTestCase(testsuite.BaseTestCase) CharArrayReader(java.io.CharArrayReader) SerialBlob(javax.sql.rowset.serial.SerialBlob) Disabled(org.junit.jupiter.api.Disabled) NativeServerSession(com.mysql.cj.protocol.a.NativeServerSession) JdbcStatement(com.mysql.cj.jdbc.JdbcStatement) BigDecimal(java.math.BigDecimal) Future(java.util.concurrent.Future) ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) MysqlXADataSource(com.mysql.cj.jdbc.MysqlXADataSource) Assumptions.assumeFalse(org.junit.jupiter.api.Assumptions.assumeFalse) ResultSet(java.sql.ResultSet) Map(java.util.Map) BigInteger(java.math.BigInteger) CharsetMappingWrapper(com.mysql.cj.CharsetMappingWrapper) NClob(java.sql.NClob) WrongArgumentException(com.mysql.cj.exceptions.WrongArgumentException) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) DataTruncation(java.sql.DataTruncation) GregorianCalendar(java.util.GregorianCalendar) ClientPreparedQuery(com.mysql.cj.ClientPreparedQuery) ParameterBindings(com.mysql.cj.jdbc.ParameterBindings) JdbcPreparedStatement(com.mysql.cj.jdbc.JdbcPreparedStatement) Reader(java.io.Reader) Assertions.assertNotSame(org.junit.jupiter.api.Assertions.assertNotSame) PreparedStatement(java.sql.PreparedStatement) ZoneId(java.time.ZoneId) Executors(java.util.concurrent.Executors) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) RowId(java.sql.RowId) Ref(java.sql.Ref) ResultSetScannerInterceptor(com.mysql.cj.jdbc.interceptors.ResultSetScannerInterceptor) Assertions.fail(org.junit.jupiter.api.Assertions.fail) MysqlErrorNumbers(com.mysql.cj.exceptions.MysqlErrorNumbers) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) ByteArrayOutputStream(java.io.ByteArrayOutputStream) UnreliableSocketFactory(testsuite.UnreliableSocketFactory) BatchUpdateException(java.sql.BatchUpdateException) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) LocalDateTime(java.time.LocalDateTime) SimpleDateFormat(java.text.SimpleDateFormat) Callable(java.util.concurrent.Callable) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) SQLException(java.sql.SQLException) Calendar(java.util.Calendar) Assumptions.assumeTrue(org.junit.jupiter.api.Assumptions.assumeTrue) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Clob(java.sql.Clob) Properties(java.util.Properties) ColumnDefinition(com.mysql.cj.protocol.ColumnDefinition) Log(com.mysql.cj.log.Log) ToIntFunction(java.util.function.ToIntFunction) ConnectionImpl(com.mysql.cj.jdbc.ConnectionImpl) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) Field(java.lang.reflect.Field) File(java.io.File) Assertions.assertSame(org.junit.jupiter.api.Assertions.assertSame) ExecutionException(java.util.concurrent.ExecutionException) StringReader(java.io.StringReader) Statement(java.sql.Statement) Connection(java.sql.Connection) Time(java.sql.Time) ExceptionFactory(com.mysql.cj.exceptions.ExceptionFactory) URL(java.net.URL) XAConnection(javax.sql.XAConnection) CachedResultSetMetaData(com.mysql.cj.jdbc.result.CachedResultSetMetaData) SQLXML(java.sql.SQLXML) TimeoutException(java.util.concurrent.TimeoutException) Array(java.sql.Array) CompletionService(java.util.concurrent.CompletionService) ResultSetInternalMethods(com.mysql.cj.jdbc.result.ResultSetInternalMethods) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) ByteArrayInputStream(java.io.ByteArrayInputStream) Locale(java.util.Locale) LocalTime(java.time.LocalTime) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) StatementsTest(testsuite.simple.StatementsTest) SQLWarning(java.sql.SQLWarning) Resultset(com.mysql.cj.protocol.Resultset) ServerSession(com.mysql.cj.protocol.ServerSession) TimeZone(java.util.TimeZone) Timestamp(java.sql.Timestamp) Query(com.mysql.cj.Query) MysqlConnectionPoolDataSource(com.mysql.cj.jdbc.MysqlConnectionPoolDataSource) Session(com.mysql.cj.Session) Test(org.junit.jupiter.api.Test) List(java.util.List) LocalDate(java.time.LocalDate) Writer(java.io.Writer) CallableStatement(java.sql.CallableStatement) MySQLTimeoutException(com.mysql.cj.jdbc.exceptions.MySQLTimeoutException) ResultSetMetaData(java.sql.ResultSetMetaData) ExecutorCompletionService(java.util.concurrent.ExecutorCompletionService) Types(java.sql.Types) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) SQLSyntaxErrorException(java.sql.SQLSyntaxErrorException) ServerPreparedQuery(com.mysql.cj.ServerPreparedQuery) ClientPreparedStatement(com.mysql.cj.jdbc.ClientPreparedStatement) CommunicationsException(com.mysql.cj.jdbc.exceptions.CommunicationsException) ExecutorService(java.util.concurrent.ExecutorService) PrintStream(java.io.PrintStream) FileWriter(java.io.FileWriter) LRUCache(com.mysql.cj.util.LRUCache) TimeUtil(com.mysql.cj.util.TimeUtil) Date(java.sql.Date) DatabaseTerm(com.mysql.cj.conf.PropertyDefinitions.DatabaseTerm) TimeUnit(java.util.concurrent.TimeUnit) StatementImpl(com.mysql.cj.jdbc.StatementImpl) BaseQueryInterceptor(testsuite.BaseQueryInterceptor) MysqlConnection(com.mysql.cj.MysqlConnection) Blob(java.sql.Blob) ResultsetRows(com.mysql.cj.protocol.ResultsetRows) PropertyKey(com.mysql.cj.conf.PropertyKey) QueryInterceptor(com.mysql.cj.interceptors.QueryInterceptor) InputStream(java.io.InputStream) Field(java.lang.reflect.Field) LRUCache(com.mysql.cj.util.LRUCache) SQLException(java.sql.SQLException) 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) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) JdbcPreparedStatement(com.mysql.cj.jdbc.JdbcPreparedStatement) PreparedStatement(java.sql.PreparedStatement) ServerPreparedStatement(com.mysql.cj.jdbc.ServerPreparedStatement) ClientPreparedStatement(com.mysql.cj.jdbc.ClientPreparedStatement) Properties(java.util.Properties) StatementsTest(testsuite.simple.StatementsTest) Test(org.junit.jupiter.api.Test)

Example 5 with ServerPreparedStatement

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

the class StatementRegressionTest method testBug81706.

/**
 * Tests fix for Bug#81706 - NullPointerException in driver.
 *
 * @throws Exception
 */
@Test
public void testBug81706() throws Exception {
    boolean useSPS = false;
    boolean cacheRsMd = false;
    boolean readOnly = false;
    do {
        final String testCase = String.format("Case [SPS: %s, CacheRsMd: %s, Read-only: %s]", useSPS ? "Y" : "N", cacheRsMd ? "Y" : "N", readOnly ? "Y" : "N");
        Properties props = new Properties();
        props.setProperty(PropertyKey.useSSL.getKeyName(), "false");
        props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        props.setProperty(PropertyKey.useServerPrepStmts.getKeyName(), Boolean.toString(useSPS));
        props.setProperty(PropertyKey.cacheResultSetMetadata.getKeyName(), Boolean.toString(cacheRsMd));
        props.setProperty(PropertyKey.queryInterceptors.getKeyName(), TestBug81706QueryInterceptor.class.getName());
        Connection testConn = getConnectionWithProps(props);
        testConn.setReadOnly(readOnly);
        Statement testStmt;
        PreparedStatement testPstmt;
        TestBug81706QueryInterceptor.isActive = true;
        TestBug81706QueryInterceptor.testCase = testCase;
        // Statement.executeQuery();
        testStmt = testConn.createStatement();
        testStmt.setFetchSize(Integer.MIN_VALUE);
        testStmt.executeQuery("/* ping */");
        testStmt.close();
        // Statemente.execute();
        testStmt = testConn.createStatement();
        testStmt.setFetchSize(Integer.MIN_VALUE);
        testStmt.execute("/* ping */");
        testStmt.close();
        // PreparedStatement.executeQuery();
        testPstmt = testConn.prepareStatement("/* ping */");
        assertFalse(testPstmt instanceof ServerPreparedStatement, testCase + ": Not the right Statement type.");
        testPstmt.setFetchSize(Integer.MIN_VALUE);
        testPstmt.executeQuery();
        testPstmt.close();
        // PreparedStatement.execute();
        testPstmt = testConn.prepareStatement("/* ping */");
        assertFalse(testPstmt instanceof ServerPreparedStatement, testCase + ": Not the right Statement type.");
        testPstmt.setFetchSize(Integer.MIN_VALUE);
        testPstmt.execute();
        testPstmt.close();
        TestBug81706QueryInterceptor.isActive = false;
        testConn.close();
    } while (// Cycle through all possible combinations.
    (useSPS = !useSPS) || (cacheRsMd = !cacheRsMd) || (readOnly = !readOnly));
}
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) 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)

Aggregations

JdbcConnection (com.mysql.cj.jdbc.JdbcConnection)30 ServerPreparedStatement (com.mysql.cj.jdbc.ServerPreparedStatement)30 Connection (java.sql.Connection)30 Test (org.junit.jupiter.api.Test)30 ClientPreparedStatement (com.mysql.cj.jdbc.ClientPreparedStatement)24 Properties (java.util.Properties)24 MysqlConnection (com.mysql.cj.MysqlConnection)21 PreparedStatement (java.sql.PreparedStatement)21 CallableStatement (java.sql.CallableStatement)18 Statement (java.sql.Statement)18 JdbcPreparedStatement (com.mysql.cj.jdbc.JdbcPreparedStatement)12 ReplicationConnection (com.mysql.cj.jdbc.ha.ReplicationConnection)12 XAConnection (javax.sql.XAConnection)12 StatementsTest (testsuite.simple.StatementsTest)12 JdbcStatement (com.mysql.cj.jdbc.JdbcStatement)9 ResultSet (java.sql.ResultSet)9 SQLException (java.sql.SQLException)9 CharsetMappingWrapper (com.mysql.cj.CharsetMappingWrapper)6 DatabaseTerm (com.mysql.cj.conf.PropertyDefinitions.DatabaseTerm)6 PropertyKey (com.mysql.cj.conf.PropertyKey)6