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();
}
}
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");
}
}
}
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));
}
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));
}
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));
}
Aggregations