use of com.mysql.cj.xdevapi.FindStatement in project aws-mysql-jdbc by awslabs.
the class SessionTest method testPreparedStatementsCleanup.
@Test
public void testPreparedStatementsCleanup() {
assumeTrue(mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.14")), "MySQL 8.0.14+ is required to run this test.");
try {
// Prepare test data.
this.schema.createCollection("testPrepStmtClean", true).add("{\"_id\":\"1\"}").execute();
SessionFactory sf = new SessionFactory();
/*
* Test common usage.
*/
Session testSession = sf.getSession(this.testProperties);
int sessionThreadId = getThreadId(testSession);
assertPreparedStatementsCount(sessionThreadId, 0, 1);
assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
// Initialize several *Statement objects.
FindStatement testFind1 = testSession.getDefaultSchema().getCollection("testPrepStmtClean").find();
SelectStatement testSelect1 = testSession.getDefaultSchema().getCollectionAsTable("testPrepStmtClean").select("_id");
FindStatement testFind2 = testSession.getDefaultSchema().getCollection("testPrepStmtClean").find();
SelectStatement testSelect2 = testSession.getDefaultSchema().getCollectionAsTable("testPrepStmtClean").select("_id");
// 1st execute -> don't prepare.
testFind1.execute();
assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
testSelect1.execute();
assertPreparedStatementsCountsAndId(testSession, 0, testSelect1, 0, -1);
testFind2.execute();
assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
testSelect2.execute();
assertPreparedStatementsCountsAndId(testSession, 0, testSelect2, 0, -1);
assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
// 2nd execute -> prepare + execute.
testFind1.execute();
assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
testSelect1.execute();
assertPreparedStatementsCountsAndId(testSession, 2, testSelect1, 2, 1);
testFind2.execute();
assertPreparedStatementsCountsAndId(testSession, 3, testFind2, 3, 1);
testSelect2.execute();
assertPreparedStatementsCountsAndId(testSession, 4, testSelect2, 4, 1);
assertPreparedStatementsStatusCounts(testSession, 4, 4, 0);
assertPreparedStatementsCount(sessionThreadId, 4, 1);
/*
* The following verifications are non-deterministic as System.gc() only hints the JVM to perform a garbage collection. This approach allows some
* time for the JVM to execute the GC. In case of failure the repeats or wait times may have to be adjusted.
* The test can be deleted entirely if no reasonable setup can be found.
*/
// Nullify first statement.
testFind1 = null;
System.gc();
int psCount, countdown = 10;
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
testSession.sql("SELECT 1").execute();
psCount = getPreparedStatementsCount(sessionThreadId);
} while (psCount != 3 && --countdown > 0);
assertPreparedStatementsStatusCounts(testSession, 4, 4, 1);
assertPreparedStatementsCount(sessionThreadId, 3, 1);
// Nullify second and third statements.
testSelect1 = null;
testFind2 = null;
System.gc();
countdown = 10;
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
testSession.sql("SELECT 1").execute();
psCount = getPreparedStatementsCount(sessionThreadId);
} while (psCount != 1 && --countdown > 0);
assertPreparedStatementsStatusCounts(testSession, 4, 4, 3);
assertPreparedStatementsCount(sessionThreadId, 1, 1);
// Nullify last statement.
testSelect2 = null;
System.gc();
countdown = 10;
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
testSession.sql("SELECT 1").execute();
psCount = getPreparedStatementsCount(sessionThreadId);
} while (psCount != 0 && --countdown > 0);
assertPreparedStatementsStatusCounts(testSession, 4, 4, 4);
assertPreparedStatementsCount(sessionThreadId, 0, 1);
testSession.close();
assertPreparedStatementsCount(sessionThreadId, 0, 1);
} finally {
this.schema.dropCollection("testPrepStmtClean");
}
}
use of com.mysql.cj.xdevapi.FindStatement in project aws-mysql-jdbc by awslabs.
the class CollectionFindTest method testPreparedStatements.
@Test
public void testPreparedStatements() {
assumeTrue(mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.14")), "MySQL 8.0.14+ is required to run this test.");
// Prepare test data.
this.collection.add("{\"_id\":\"1\", \"ord\": 1}", "{\"_id\":\"2\", \"ord\": 2}", "{\"_id\":\"3\", \"ord\": 3}", "{\"_id\":\"4\", \"ord\": 4}", "{\"_id\":\"5\", \"ord\": 5}", "{\"_id\":\"6\", \"ord\": 6}", "{\"_id\":\"7\", \"ord\": 7}", "{\"_id\":\"8\", \"ord\": 8}").execute();
SessionFactory sf = new SessionFactory();
/*
* Test common usage.
*/
Session testSession = sf.getSession(this.testProperties);
int sessionThreadId = getThreadId(testSession);
assertPreparedStatementsCount(sessionThreadId, 0, 1);
assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
Collection testCol = testSession.getDefaultSchema().getCollection(this.collectionName);
// Initialize several FindStatement objects.
// Find all.
FindStatement testFind1 = testCol.find();
// Criteria with one placeholder.
FindStatement testFind2 = testCol.find("$.ord >= :n");
// Criteria with same placeholder repeated.
FindStatement testFind3 = testCol.find("$.ord >= :n AND $.ord <= :n + 3");
// Criteria with multiple placeholders.
FindStatement testFind4 = testCol.find("$.ord >= :n AND $.ord <= :m");
assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
assertPreparedStatementsCountsAndId(testSession, 0, testFind3, 0, -1);
assertPreparedStatementsCountsAndId(testSession, 0, testFind4, 0, -1);
assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
// A. Set binds: 1st execute -> non-prepared.
assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
assertTestPreparedStatementsResult(testFind2.bind("n", 2).execute(), 2, 8);
assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
assertTestPreparedStatementsResult(testFind3.bind("n", 2).execute(), 2, 5);
assertPreparedStatementsCountsAndId(testSession, 0, testFind3, 0, -1);
assertTestPreparedStatementsResult(testFind4.bind("n", 2).bind("m", 5).execute(), 2, 5);
assertPreparedStatementsCountsAndId(testSession, 0, testFind4, 0, -1);
assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
// B. Set sort resets execution count: 1st execute -> non-prepared.
assertTestPreparedStatementsResult(testFind1.sort("$._id").execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
assertTestPreparedStatementsResult(testFind2.sort("$._id").execute(), 2, 8);
assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
assertTestPreparedStatementsResult(testFind3.sort("$._id").execute(), 2, 5);
assertPreparedStatementsCountsAndId(testSession, 0, testFind3, 0, -1);
assertTestPreparedStatementsResult(testFind4.sort("$._id").execute(), 2, 5);
assertPreparedStatementsCountsAndId(testSession, 0, testFind4, 0, -1);
assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
// C. Set binds reuse statement: 2nd execute -> prepare + execute.
assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
assertTestPreparedStatementsResult(testFind2.bind("n", 3).execute(), 3, 8);
assertPreparedStatementsCountsAndId(testSession, 2, testFind2, 2, 1);
assertTestPreparedStatementsResult(testFind3.bind("n", 3).execute(), 3, 6);
assertPreparedStatementsCountsAndId(testSession, 3, testFind3, 3, 1);
assertTestPreparedStatementsResult(testFind4.bind("m", 6).execute(), 2, 6);
assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 1);
assertPreparedStatementsStatusCounts(testSession, 4, 4, 0);
// D. Set binds reuse statement: 3rd execute -> execute.
assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 4, testFind1, 1, 2);
assertTestPreparedStatementsResult(testFind2.bind("n", 4).execute(), 4, 8);
assertPreparedStatementsCountsAndId(testSession, 4, testFind2, 2, 2);
assertTestPreparedStatementsResult(testFind3.bind("n", 4).execute(), 4, 7);
assertPreparedStatementsCountsAndId(testSession, 4, testFind3, 3, 2);
assertTestPreparedStatementsResult(testFind4.bind("n", 3).bind("m", 7).execute(), 3, 7);
assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 2);
assertPreparedStatementsStatusCounts(testSession, 4, 8, 0);
// E. Set sort deallocates and resets execution count: 1st execute -> deallocate + non-prepared.
assertTestPreparedStatementsResult(testFind1.sort("$._id").execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 3, testFind1, 0, -1);
assertTestPreparedStatementsResult(testFind2.sort("$._id").bind("n", 4).execute(), 4, 8);
assertPreparedStatementsCountsAndId(testSession, 2, testFind2, 0, -1);
assertTestPreparedStatementsResult(testFind3.sort("$._id").bind("n", 4).execute(), 4, 7);
assertPreparedStatementsCountsAndId(testSession, 1, testFind3, 0, -1);
assertTestPreparedStatementsResult(testFind4.sort("$._id").bind("n", 3).bind("m", 7).execute(), 3, 7);
assertPreparedStatementsCountsAndId(testSession, 0, testFind4, 0, -1);
assertPreparedStatementsStatusCounts(testSession, 4, 8, 4);
// F. No Changes: 2nd execute -> prepare + execute.
assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
assertTestPreparedStatementsResult(testFind2.bind("n", 4).execute(), 4, 8);
assertPreparedStatementsCountsAndId(testSession, 2, testFind2, 2, 1);
assertTestPreparedStatementsResult(testFind3.bind("n", 4).execute(), 4, 7);
assertPreparedStatementsCountsAndId(testSession, 3, testFind3, 3, 1);
assertTestPreparedStatementsResult(testFind4.bind("n", 3).bind("m", 7).execute(), 3, 7);
assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 1);
assertPreparedStatementsStatusCounts(testSession, 8, 12, 4);
// G. Set limit for the first time deallocates and re-prepares: 1st execute -> re-prepare + execute.
assertTestPreparedStatementsResult(testFind1.limit(2).execute(), 1, 2);
assertPreparedStatementsCountsAndId(testSession, 4, testFind1, 1, 1);
assertTestPreparedStatementsResult(testFind2.limit(2).execute(), 4, 5);
assertPreparedStatementsCountsAndId(testSession, 4, testFind2, 2, 1);
assertTestPreparedStatementsResult(testFind3.limit(2).execute(), 4, 5);
assertPreparedStatementsCountsAndId(testSession, 4, testFind3, 3, 1);
assertTestPreparedStatementsResult(testFind4.limit(2).execute(), 3, 4);
assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 1);
assertPreparedStatementsStatusCounts(testSession, 12, 16, 8);
// H. Set limit and offset reuse prepared statement: 2nd execute -> execute.
assertTestPreparedStatementsResult(testFind1.limit(1).offset(1).execute(), 2, 2);
assertPreparedStatementsCountsAndId(testSession, 4, testFind1, 1, 2);
assertTestPreparedStatementsResult(testFind2.limit(1).offset(1).execute(), 5, 5);
assertPreparedStatementsCountsAndId(testSession, 4, testFind2, 2, 2);
assertTestPreparedStatementsResult(testFind3.limit(1).offset(1).execute(), 5, 5);
assertPreparedStatementsCountsAndId(testSession, 4, testFind3, 3, 2);
assertTestPreparedStatementsResult(testFind4.limit(1).offset(1).execute(), 4, 4);
assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 2);
assertPreparedStatementsStatusCounts(testSession, 12, 20, 8);
// I. Set sort deallocates and resets execution count, set limit and bind has no effect: 1st execute -> deallocate + non-prepared.
assertTestPreparedStatementsResult(testFind1.sort("$._id").limit(2).execute(), 2, 3);
assertPreparedStatementsCountsAndId(testSession, 3, testFind1, 0, -1);
assertTestPreparedStatementsResult(testFind2.sort("$._id").limit(2).bind("n", 4).execute(), 5, 6);
assertPreparedStatementsCountsAndId(testSession, 2, testFind2, 0, -1);
assertTestPreparedStatementsResult(testFind3.sort("$._id").limit(2).bind("n", 4).execute(), 5, 6);
assertPreparedStatementsCountsAndId(testSession, 1, testFind3, 0, -1);
assertTestPreparedStatementsResult(testFind4.sort("$._id").limit(2).bind("n", 3).bind("m", 7).execute(), 4, 5);
assertPreparedStatementsCountsAndId(testSession, 0, testFind4, 0, -1);
assertPreparedStatementsStatusCounts(testSession, 12, 20, 12);
// J. Set offset reuse statement: 2nd execute -> prepare + execute.
assertTestPreparedStatementsResult(testFind1.offset(0).execute(), 1, 2);
assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
assertTestPreparedStatementsResult(testFind2.offset(0).execute(), 4, 5);
assertPreparedStatementsCountsAndId(testSession, 2, testFind2, 2, 1);
assertTestPreparedStatementsResult(testFind3.offset(0).execute(), 4, 5);
assertPreparedStatementsCountsAndId(testSession, 3, testFind3, 3, 1);
assertTestPreparedStatementsResult(testFind4.offset(0).execute(), 3, 4);
assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 1);
assertPreparedStatementsStatusCounts(testSession, 16, 24, 12);
testSession.close();
// Prepared statements won't live past the closing of the session.
assertPreparedStatementsCount(sessionThreadId, 0, 10);
/*
* Test falling back onto non-prepared statements.
*/
testSession = sf.getSession(this.testProperties);
int origMaxPrepStmtCount = this.session.sql("SELECT @@max_prepared_stmt_count").execute().fetchOne().getInt(0);
try {
// Allow preparing only one more statement.
this.session.sql("SET GLOBAL max_prepared_stmt_count = ?").bind(getPreparedStatementsCount() + 1).execute();
sessionThreadId = getThreadId(testSession);
assertPreparedStatementsCount(sessionThreadId, 0, 1);
assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
testCol = testSession.getDefaultSchema().getCollection(this.collectionName);
testFind1 = testCol.find();
testFind2 = testCol.find();
// 1st execute -> don't prepare.
assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
assertTestPreparedStatementsResult(testFind2.execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
// 2nd execute -> prepare + execute.
assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
// Fails preparing, execute as non-prepared.
assertTestPreparedStatementsResult(testFind2.execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 1, testFind2, 0, -1);
// Failed prepare also counts.
assertPreparedStatementsStatusCounts(testSession, 2, 1, 0);
// 3rd execute -> execute.
assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 2);
// Execute as non-prepared.
assertTestPreparedStatementsResult(testFind2.execute(), 1, 8);
assertPreparedStatementsCountsAndId(testSession, 1, testFind2, 0, -1);
assertPreparedStatementsStatusCounts(testSession, 2, 2, 0);
testSession.close();
// Prepared statements won't live past the closing of the session.
assertPreparedStatementsCount(sessionThreadId, 0, 10);
} finally {
this.session.sql("SET GLOBAL max_prepared_stmt_count = ?").bind(origMaxPrepStmtCount).execute();
}
}
use of com.mysql.cj.xdevapi.FindStatement in project aws-mysql-jdbc by awslabs.
the class CollectionFindTest method testDeprecateWhere.
@Test
@SuppressWarnings("deprecation")
public void testDeprecateWhere() throws Exception {
this.collection.add("{\"_id\":\"1\", \"ord\": 1}", "{\"_id\":\"2\", \"ord\": 2}", "{\"_id\":\"3\", \"ord\": 3}", "{\"_id\":\"4\", \"ord\": 4}", "{\"_id\":\"5\", \"ord\": 5}", "{\"_id\":\"6\", \"ord\": 6}", "{\"_id\":\"7\", \"ord\": 7}", "{\"_id\":\"8\", \"ord\": 8}").execute();
FindStatement testFind = this.collection.find("$.ord <= 2");
assertTrue(testFind.getClass().getMethod("where", String.class).isAnnotationPresent(Deprecated.class));
assertEquals(2, testFind.execute().count());
assertEquals(4, ((FindStatementImpl) testFind).where("$.ord > 4").execute().count());
}
use of com.mysql.cj.xdevapi.FindStatement in project aws-mysql-jdbc by awslabs.
the class SessionTest method testPreparedStatementsPooledConnections.
@Test
public void testPreparedStatementsPooledConnections() {
assumeTrue(mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.14")), "MySQL 8.0.14+ is required to run this test.");
Properties props = new Properties();
props.setProperty(ClientProperty.POOLING_ENABLED.getKeyName(), "true");
props.setProperty(ClientProperty.POOLING_MAX_SIZE.getKeyName(), "1");
try {
this.schema.createCollection("testPrepStmtPooling", true).add("{\"_id\":\"1\"}").execute();
ClientFactory cf = new ClientFactory();
Client testClient = cf.getClient(this.baseUrl, props);
Session testSession = testClient.getSession();
int sessionThreadId = getThreadId(testSession);
assertPreparedStatementsCount(sessionThreadId, 0, 1);
FindStatement testFind = testSession.getDefaultSchema().getCollection("testPrepStmtPooling").find();
// 1st execute -> don't prepare.
testFind.execute();
assertPreparedStatementsCountsAndId(testSession, 0, testFind, 0, -1);
assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
// 2nd execute -> prepare + execute.
testFind.execute();
assertPreparedStatementsCountsAndId(testSession, 1, testFind, 1, 1);
assertPreparedStatementsStatusCounts(testSession, 1, 1, 0);
assertPreparedStatementsCount(sessionThreadId, 1, 1);
// Prepared statements won't live past closing the session, or returning it to the pool.
testSession.close();
assertPreparedStatementsCount(sessionThreadId, 0, 10);
testSession = testClient.getSession();
sessionThreadId = getThreadId(testSession);
assertPreparedStatementsCount(sessionThreadId, 0, 1);
// The underlying connection object in testFind is the same as the one returned from the pool to the new session.
// This exec attempt counts.
assertThrows(XProtocolError.class, "ERROR 5110 \\(HY000\\) Statement with ID=1 was not prepared", testFind::execute);
if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.16"))) {
// Mysqlx.Session.Reset doesn't clear PS counters.
assertPreparedStatementsStatusCounts(testSession, 1, 2, 0);
} else {
assertPreparedStatementsStatusCounts(testSession, 0, 1, 0);
}
testFind = testSession.getDefaultSchema().getCollection("testPrepStmtPooling").find();
// 1st execute -> don't prepare.
testFind.execute();
assertPreparedStatementsCountsAndId(testSession, 0, testFind, 0, -1);
if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.16"))) {
// Mysqlx.Session.Reset doesn't clear PS counters.
assertPreparedStatementsStatusCounts(testSession, 1, 2, 0);
} else {
assertPreparedStatementsStatusCounts(testSession, 0, 1, 0);
}
// 2nd execute -> prepare + execute.
testFind.execute();
assertPreparedStatementsCountsAndId(testSession, 1, testFind, 1, 1);
if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.16"))) {
// Mysqlx.Session.Reset doesn't clear PS counters.
assertPreparedStatementsStatusCounts(testSession, 2, 3, 0);
} else {
assertPreparedStatementsStatusCounts(testSession, 1, 2, 0);
}
assertPreparedStatementsCount(sessionThreadId, 1, 1);
// Prepared statements won't live past closing the client and its sessions.
testClient.close();
assertPreparedStatementsCount(sessionThreadId, 0, 10);
assertThrows(CJCommunicationsException.class, "Unable to write message", testFind::execute);
} finally {
this.schema.dropCollection("testPrepStmtPooling");
}
}
Aggregations