Search in sources :

Example 81 with Session

use of com.mysql.cj.xdevapi.Session in project aws-mysql-jdbc by awslabs.

the class TableSelectTest method testTableRowLockOptions.

@Test
public void testTableRowLockOptions() throws Exception {
    assumeTrue(mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.5")), "MySQL 8.0.5+ is required to run this test.");
    Function<RowResult, List<String>> asStringList = rr -> rr.fetchAll().stream().map(r -> r.getString(0)).collect(Collectors.toList());
    sqlUpdate("DROP TABLE IF EXISTS testTableRowLockOptions");
    sqlUpdate("CREATE TABLE testTableRowLockOptions (_id VARCHAR(32), a VARCHAR(20))");
    // index is required to enable row locking
    sqlUpdate("CREATE UNIQUE INDEX myIndex ON testTableRowLockOptions (_id)");
    sqlUpdate("INSERT INTO testTableRowLockOptions VALUES ('1', '1'), ('2', '1'), ('3', '1')");
    Session session1 = null;
    Session session2 = null;
    try {
        session1 = new SessionFactory().getSession(this.testProperties);
        Table table1 = session1.getDefaultSchema().getTable("testTableRowLockOptions");
        session2 = new SessionFactory().getSession(this.testProperties);
        Table table2 = session2.getDefaultSchema().getTable("testTableRowLockOptions");
        RowResult res;
        CompletableFuture<RowResult> futRes;
        /*
             * 1. Shared Lock in both sessions.
             */
        // session2.lockShared() returns data immediately.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockShared().execute();
        session2.startTransaction();
        res = table2.select("_id").where("_id < '3'").lockShared().execute();
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("1", "2"));
        session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockShared().executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("1", "2"));
        session2.rollback();
        session1.rollback();
        // session2.lockShared(NOWAIT) returns data immediately.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockShared().execute();
        session2.startTransaction();
        res = table2.select("_id").where("_id < '3'").lockShared(Statement.LockContention.NOWAIT).execute();
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("1", "2"));
        session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockShared(Statement.LockContention.NOWAIT).executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("1", "2"));
        session2.rollback();
        session1.rollback();
        // session2.lockShared(SKIP_LOCK) returns data immediately.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockShared().execute();
        session2.startTransaction();
        res = table2.select("_id").where("_id < '3'").lockShared(Statement.LockContention.SKIP_LOCKED).execute();
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("1", "2"));
        session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockShared(Statement.LockContention.SKIP_LOCKED).executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("1", "2"));
        session2.rollback();
        session1.rollback();
        /*
             * 2. Shared Lock in first session and exclusive lock in second.
             */
        // session2.lockExclusive() blocks until session1 ends.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockShared().execute();
        // session2.startTransaction();
        // res = table2.select("_id").where("_id < '3'").lockExclusive().execute(); (Can't test)
        // session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockExclusive().executeAsync();
        final CompletableFuture<RowResult> fr1 = futRes;
        assertThrows(TimeoutException.class, () -> fr1.get(3, TimeUnit.SECONDS));
        // Unlocks session2.
        session1.rollback();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("1", "2"));
        session2.rollback();
        // session2.lockExclusive(NOWAIT) should return locking error.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockShared().execute();
        session2.startTransaction();
        assertThrows(XProtocolError.class, "ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> table2.select("_id").where("_id < '3'").lockExclusive(Statement.LockContention.NOWAIT).execute());
        session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockExclusive(Statement.LockContention.NOWAIT).executeAsync();
        final CompletableFuture<RowResult> fr2 = futRes;
        assertThrows(ExecutionException.class, ".*XProtocolError: ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> fr2.get(3, TimeUnit.SECONDS));
        session2.rollback();
        session1.rollback();
        // session2.lockExclusive(SKIP_LOCK) should return (unlocked) data immediately.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockShared().execute();
        session2.startTransaction();
        res = table2.select("_id").where("_id < '3'").lockExclusive(Statement.LockContention.SKIP_LOCKED).execute();
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("2"));
        session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockExclusive(Statement.LockContention.SKIP_LOCKED).executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("2"));
        session2.rollback();
        session1.rollback();
        /*
             * 3. Exclusive Lock in first session and shared lock in second.
             */
        // session2.lockShared() blocks until session1 ends.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockExclusive().execute();
        // session2.startTransaction();
        // res = table2.select("_id").where("_id < '3'").lockShared().execute(); (Can't test)
        // session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockShared().executeAsync();
        final CompletableFuture<RowResult> fr3 = futRes;
        assertThrows(TimeoutException.class, () -> fr3.get(3, TimeUnit.SECONDS));
        // Unlocks session2.
        session1.rollback();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("1", "2"));
        session2.rollback();
        // session2.lockShared(NOWAIT) should return locking error.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockExclusive().execute();
        session2.startTransaction();
        assertThrows(XProtocolError.class, "ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> table2.select("_id").where("_id < '3'").lockShared(Statement.LockContention.NOWAIT).execute());
        session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockShared(Statement.LockContention.NOWAIT).executeAsync();
        final CompletableFuture<RowResult> fr4 = futRes;
        assertThrows(ExecutionException.class, ".*XProtocolError: ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> fr4.get(3, TimeUnit.SECONDS));
        session2.rollback();
        session1.rollback();
        // session2.lockShared(SKIP_LOCK) should return (unlocked) data immediately.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockExclusive().execute();
        session2.startTransaction();
        res = table2.select("_id").where("_id < '3'").lockShared(Statement.LockContention.SKIP_LOCKED).execute();
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("2"));
        session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockShared(Statement.LockContention.SKIP_LOCKED).executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("2"));
        session2.rollback();
        session1.rollback();
        /*
             * 4. Exclusive Lock in both sessions.
             */
        // session2.lockExclusive() blocks until session1 ends.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockExclusive().execute();
        // session2.startTransaction();
        // res = table2.select("_id").where("_id < '3'").lockExclusive().execute(); (Can't test)
        // session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockExclusive().executeAsync();
        final CompletableFuture<RowResult> fr5 = futRes;
        assertThrows(TimeoutException.class, () -> fr5.get(3, TimeUnit.SECONDS));
        // Unlocks session2.
        session1.rollback();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("1", "2"));
        session2.rollback();
        // session2.lockExclusive(NOWAIT) should return locking error.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockExclusive().execute();
        session2.startTransaction();
        assertThrows(XProtocolError.class, "ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> table2.select("_id").where("_id < '3'").lockExclusive(Statement.LockContention.NOWAIT).execute());
        session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockExclusive(Statement.LockContention.NOWAIT).executeAsync();
        final CompletableFuture<RowResult> fr6 = futRes;
        assertThrows(ExecutionException.class, ".*XProtocolError: ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> fr6.get(3, TimeUnit.SECONDS));
        session2.rollback();
        session1.rollback();
        // session2.lockExclusive(SKIP_LOCK) should return (unlocked) data immediately.
        session1.startTransaction();
        table1.select("_id").where("_id = '1'").lockExclusive().execute();
        session2.startTransaction();
        res = table2.select("_id").where("_id < '3'").lockExclusive(Statement.LockContention.SKIP_LOCKED).execute();
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("2"));
        session2.rollback();
        session2.startTransaction();
        futRes = table2.select("_id").where("_id < '3'").lockExclusive(Statement.LockContention.SKIP_LOCKED).executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("2"));
        session2.rollback();
        session1.rollback();
    } finally {
        if (session1 != null) {
            session1.close();
        }
        if (session2 != null) {
            session2.close();
        }
        sqlUpdate("DROP TABLE IF EXISTS testTableRowLockOptions");
    }
}
Also used : RowResult(com.mysql.cj.xdevapi.RowResult) Type(com.mysql.cj.xdevapi.Type) TimeoutException(java.util.concurrent.TimeoutException) HashMap(java.util.HashMap) Callable(java.util.concurrent.Callable) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) Statement(com.mysql.cj.xdevapi.Statement) BigDecimal(java.math.BigDecimal) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) Map(java.util.Map) Assumptions.assumeTrue(org.junit.jupiter.api.Assumptions.assumeTrue) CoreSession(com.mysql.cj.CoreSession) BigInteger(java.math.BigInteger) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Column(com.mysql.cj.xdevapi.Column) SessionImpl(com.mysql.cj.xdevapi.SessionImpl) Table(com.mysql.cj.xdevapi.Table) ServerVersion(com.mysql.cj.ServerVersion) Session(com.mysql.cj.xdevapi.Session) CoreMatchers.hasItems(org.hamcrest.CoreMatchers.hasItems) Field(java.lang.reflect.Field) Collectors(java.util.stream.Collectors) DataConversionException(com.mysql.cj.exceptions.DataConversionException) XProtocolError(com.mysql.cj.protocol.x.XProtocolError) SessionFactory(com.mysql.cj.xdevapi.SessionFactory) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) Row(com.mysql.cj.xdevapi.Row) SqlResult(com.mysql.cj.xdevapi.SqlResult) List(java.util.List) SelectStatement(com.mysql.cj.xdevapi.SelectStatement) XProtocol(com.mysql.cj.protocol.x.XProtocol) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) PropertyKey(com.mysql.cj.conf.PropertyKey) SessionFactory(com.mysql.cj.xdevapi.SessionFactory) RowResult(com.mysql.cj.xdevapi.RowResult) Table(com.mysql.cj.xdevapi.Table) List(java.util.List) CoreSession(com.mysql.cj.CoreSession) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 82 with Session

use of com.mysql.cj.xdevapi.Session in project aws-mysql-jdbc by awslabs.

the class TableSelectTest method testBug22038729.

/**
 * Tests fix for Bug#22038729, X DEVAPI: ANY API CALL AFTER A FAILED CALL PROC() RESULTS IN HANG
 * and for duplicate Bug#25575010, X DEVAPI: ANY API CALL AFTER A FAILED SELECT RESULTS IN HANG
 *
 * @throws Exception
 */
@Test
public void testBug22038729() throws Exception {
    final Field pf = CoreSession.class.getDeclaredField("protocol");
    pf.setAccessible(true);
    try {
        sqlUpdate("drop table if exists testBug22038729");
        sqlUpdate("create table testBug22038729 (c1 int, c2 int unsigned, id bigint)");
        sqlUpdate("insert into testBug22038729 values(10, 100, -9223372036854775808)");
        sqlUpdate("insert into testBug22038729 values(11, 11, 9223372036854775806)");
        sqlUpdate("drop procedure if exists testBug22038729p");
        sqlUpdate("create procedure testBug22038729p (in p1 int,IN p2 char(20)) begin select -10;select id+1000 from testBug22038729; end;");
        // XProtocol.readRowOrNull()
        Session sess = new SessionFactory().getSession(this.testProperties);
        Table t1 = sess.getDefaultSchema().getTable("testBug22038729");
        RowResult rows = t1.select("c1-c2").orderBy("c1 DESC").execute();
        assertTrue(rows.hasNext());
        Row r = rows.next();
        assertEquals(0, r.getInt(0));
        assertThrows(XProtocolError.class, "ERROR 1690 \\(22003\\) BIGINT UNSIGNED value is out of range .*", () -> rows.hasNext());
        // It was hanging
        sess.close();
        // XProtocol.readRowOrNull()
        sess = new SessionFactory().getSession(this.testProperties);
        SqlResult rs1 = sess.sql("select c1-c2 from testBug22038729 order by c1 desc").execute();
        assertEquals(0, rs1.fetchOne().getInt(0));
        assertThrows(XProtocolError.class, "ERROR 1690 \\(22003\\) BIGINT UNSIGNED value is out of range .*", () -> rs1.fetchOne());
        // It was hanging
        sess.close();
        // XProtocol.drainRows()
        sess = new SessionFactory().getSession(this.testProperties);
        sess.sql("select c1-c2 from testBug22038729 order by c1 desc").execute();
        XProtocol xp = (XProtocol) pf.get(((SessionImpl) sess).getSession());
        assertThrows(XProtocolError.class, "ERROR 1690 \\(22003\\) BIGINT UNSIGNED value is out of range .*", () -> {
            xp.drainRows();
            return xp;
        });
        // It was hanging
        sess.close();
        sess = new SessionFactory().getSession(this.testProperties);
        SqlResult rs2 = sess.sql("call testBug22038729p(?, ?)").bind(10).bind("X").execute();
        assertTrue(rs2.hasData());
        assertTrue(rs2.hasNext());
        r = rs2.next();
        assertEquals(-10, r.getInt(0));
        assertFalse(rs2.hasNext());
        assertTrue(rs2.nextResult());
        assertTrue(rs2.hasData());
        assertTrue(rs2.hasNext());
        r = rs2.next();
        assertEquals(-9223372036854774808L, r.getLong(0));
        assertThrows(XProtocolError.class, "ERROR 1690 \\(22003\\) BIGINT value is out of range .*", () -> rs2.hasNext());
        // It was hanging
        sess.close();
    } finally {
        sqlUpdate("drop table if exists testBug22038729");
        sqlUpdate("drop procedure if exists testBug22038729p");
    }
}
Also used : SessionFactory(com.mysql.cj.xdevapi.SessionFactory) Field(java.lang.reflect.Field) RowResult(com.mysql.cj.xdevapi.RowResult) Table(com.mysql.cj.xdevapi.Table) SqlResult(com.mysql.cj.xdevapi.SqlResult) Row(com.mysql.cj.xdevapi.Row) XProtocol(com.mysql.cj.protocol.x.XProtocol) SessionImpl(com.mysql.cj.xdevapi.SessionImpl) CoreSession(com.mysql.cj.CoreSession) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 83 with Session

use of com.mysql.cj.xdevapi.Session in project aws-mysql-jdbc by awslabs.

the class TableUpdateTest method testPreparedStatements.

@Test
public void testPreparedStatements() {
    assumeTrue(mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.14")), "MySQL 8.0.14+ is required to run this test.");
    try {
        // Prepare test data.
        testPreparedStatementsResetData();
        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);
        Table testTbl1 = testSession.getDefaultSchema().getTable("testPrepareUpdate_1");
        Table testTbl2 = testSession.getDefaultSchema().getTable("testPrepareUpdate_2");
        Table testTbl3 = testSession.getDefaultSchema().getTable("testPrepareUpdate_3");
        Table testTbl4 = testSession.getDefaultSchema().getTable("testPrepareUpdate_4");
        // Initialize several UpdateStatement objects.
        // Update all.
        UpdateStatement testUpdate1 = testTbl1.update().where("true").set("ord", expr("ord * 10"));
        // Criteria with one placeholder.
        UpdateStatement testUpdate2 = testTbl2.update().where("ord >= :n").set("ord", expr("ord * 10"));
        // Criteria with same placeholder repeated.
        UpdateStatement testupdate3 = testTbl3.update().where("ord >= :n AND ord <= :n + 1").set("ord", expr("ord * 10"));
        // Criteria with multiple placeholders.
        UpdateStatement testUpdate4 = testTbl4.update().where("ord >= :n AND ord <= :m").set("ord", expr("ord * 10"));
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate1, 0, -1);
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate2, 0, -1);
        assertPreparedStatementsCountsAndId(testSession, 0, testupdate3, 0, -1);
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate4, 0, -1);
        // A. Set binds: 1st execute -> non-prepared.
        assertTestPreparedStatementsResult(testUpdate1.execute(), 4, testTbl1.getName(), 10, 20, 30, 40);
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate1, 0, -1);
        assertTestPreparedStatementsResult(testUpdate2.bind("n", 2).execute(), 3, testTbl2.getName(), 1, 20, 30, 40);
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate2, 0, -1);
        assertTestPreparedStatementsResult(testupdate3.bind("n", 2).execute(), 2, testTbl3.getName(), 1, 20, 30, 4);
        assertPreparedStatementsCountsAndId(testSession, 0, testupdate3, 0, -1);
        assertTestPreparedStatementsResult(testUpdate4.bind("n", 2).bind("m", 3).execute(), 2, testTbl4.getName(), 1, 20, 30, 4);
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate4, 0, -1);
        assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
        testPreparedStatementsResetData();
        // B. Set orderBy resets execution count: 1st execute -> non-prepared.
        assertTestPreparedStatementsResult(testUpdate1.orderBy("id").execute(), 4, testTbl1.getName(), 10, 20, 30, 40);
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate1, 0, -1);
        assertTestPreparedStatementsResult(testUpdate2.orderBy("id").execute(), 3, testTbl2.getName(), 1, 20, 30, 40);
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate2, 0, -1);
        assertTestPreparedStatementsResult(testupdate3.orderBy("id").execute(), 2, testTbl3.getName(), 1, 20, 30, 4);
        assertPreparedStatementsCountsAndId(testSession, 0, testupdate3, 0, -1);
        assertTestPreparedStatementsResult(testUpdate4.orderBy("id").execute(), 2, testTbl4.getName(), 1, 20, 30, 4);
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate4, 0, -1);
        assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
        testPreparedStatementsResetData();
        // C. Set binds reuse statement: 2nd execute -> prepare + execute.
        assertTestPreparedStatementsResult(testUpdate1.execute(), 4, testTbl1.getName(), 10, 20, 30, 40);
        assertPreparedStatementsCountsAndId(testSession, 1, testUpdate1, 1, 1);
        assertTestPreparedStatementsResult(testUpdate2.bind("n", 3).execute(), 2, testTbl2.getName(), 1, 2, 30, 40);
        assertPreparedStatementsCountsAndId(testSession, 2, testUpdate2, 2, 1);
        assertTestPreparedStatementsResult(testupdate3.bind("n", 3).execute(), 2, testTbl3.getName(), 1, 2, 30, 40);
        assertPreparedStatementsCountsAndId(testSession, 3, testupdate3, 3, 1);
        assertTestPreparedStatementsResult(testUpdate4.bind("m", 4).execute(), 3, testTbl4.getName(), 1, 20, 30, 40);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate4, 4, 1);
        assertPreparedStatementsStatusCounts(testSession, 4, 4, 0);
        testPreparedStatementsResetData();
        // D. Set binds reuse statement: 3rd execute -> execute.
        assertTestPreparedStatementsResult(testUpdate1.execute(), 4, testTbl1.getName(), 10, 20, 30, 40);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate1, 1, 2);
        assertTestPreparedStatementsResult(testUpdate2.bind("n", 4).execute(), 1, testTbl2.getName(), 1, 2, 3, 40);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate2, 2, 2);
        assertTestPreparedStatementsResult(testupdate3.bind("n", 1).execute(), 2, testTbl3.getName(), 10, 20, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 4, testupdate3, 3, 2);
        assertTestPreparedStatementsResult(testUpdate4.bind("m", 2).execute(), 1, testTbl4.getName(), 1, 20, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate4, 4, 2);
        assertPreparedStatementsStatusCounts(testSession, 4, 8, 0);
        testPreparedStatementsResetData();
        // E. Set new values deallocates and resets execution count: 1st execute -> deallocate + non-prepared.
        assertTestPreparedStatementsResult(testUpdate1.set("ord", expr("ord * 100")).execute(), 4, testTbl1.getName(), 100, 200, 300, 400);
        assertPreparedStatementsCountsAndId(testSession, 3, testUpdate1, 0, -1);
        assertTestPreparedStatementsResult(testUpdate2.set("ord", expr("ord * 100")).execute(), 1, testTbl2.getName(), 1, 2, 3, 400);
        assertPreparedStatementsCountsAndId(testSession, 2, testUpdate2, 0, -1);
        assertTestPreparedStatementsResult(testupdate3.set("ord", expr("ord * 100")).execute(), 2, testTbl3.getName(), 100, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 1, testupdate3, 0, -1);
        assertTestPreparedStatementsResult(testUpdate4.set("ord", expr("ord * 100")).execute(), 1, testTbl4.getName(), 1, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate4, 0, -1);
        assertPreparedStatementsStatusCounts(testSession, 4, 8, 4);
        testPreparedStatementsResetData();
        // F. No Changes: 2nd execute -> prepare + execute.
        assertTestPreparedStatementsResult(testUpdate1.execute(), 4, testTbl1.getName(), 100, 200, 300, 400);
        assertPreparedStatementsCountsAndId(testSession, 1, testUpdate1, 1, 1);
        assertTestPreparedStatementsResult(testUpdate2.execute(), 1, testTbl2.getName(), 1, 2, 3, 400);
        assertPreparedStatementsCountsAndId(testSession, 2, testUpdate2, 2, 1);
        assertTestPreparedStatementsResult(testupdate3.execute(), 2, testTbl3.getName(), 100, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 3, testupdate3, 3, 1);
        assertTestPreparedStatementsResult(testUpdate4.execute(), 1, testTbl4.getName(), 1, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate4, 4, 1);
        assertPreparedStatementsStatusCounts(testSession, 8, 12, 4);
        testPreparedStatementsResetData();
        // G. Set limit for the first time deallocates and re-prepares: 1st execute -> re-prepare + execute.
        assertTestPreparedStatementsResult(testUpdate1.limit(1).execute(), 1, testTbl1.getName(), 100, 2, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate1, 1, 1);
        assertTestPreparedStatementsResult(testUpdate2.limit(1).execute(), 1, testTbl2.getName(), 1, 2, 3, 400);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate2, 2, 1);
        assertTestPreparedStatementsResult(testupdate3.limit(1).execute(), 1, testTbl3.getName(), 100, 2, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 4, testupdate3, 3, 1);
        assertTestPreparedStatementsResult(testUpdate4.limit(1).execute(), 1, testTbl4.getName(), 1, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate4, 4, 1);
        assertPreparedStatementsStatusCounts(testSession, 12, 16, 8);
        testPreparedStatementsResetData();
        // H. Set limit reuse prepared statement: 2nd execute -> execute.
        assertTestPreparedStatementsResult(testUpdate1.limit(2).execute(), 2, testTbl1.getName(), 100, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate1, 1, 2);
        assertTestPreparedStatementsResult(testUpdate2.limit(2).execute(), 1, testTbl2.getName(), 1, 2, 3, 400);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate2, 2, 2);
        assertTestPreparedStatementsResult(testupdate3.limit(2).execute(), 2, testTbl3.getName(), 100, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 4, testupdate3, 3, 2);
        assertTestPreparedStatementsResult(testUpdate4.limit(2).execute(), 1, testTbl4.getName(), 1, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate4, 4, 2);
        assertPreparedStatementsStatusCounts(testSession, 12, 20, 8);
        testPreparedStatementsResetData();
        // I. Set orderBy deallocates and resets execution count, set limit has no effect: 1st execute -> deallocate + non-prepared.
        assertTestPreparedStatementsResult(testUpdate1.orderBy("id").limit(1).execute(), 1, testTbl1.getName(), 100, 2, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 3, testUpdate1, 0, -1);
        assertTestPreparedStatementsResult(testUpdate2.orderBy("id").limit(1).execute(), 1, testTbl2.getName(), 1, 2, 3, 400);
        assertPreparedStatementsCountsAndId(testSession, 2, testUpdate2, 0, -1);
        assertTestPreparedStatementsResult(testupdate3.orderBy("id").limit(1).execute(), 1, testTbl3.getName(), 100, 2, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 1, testupdate3, 0, -1);
        assertTestPreparedStatementsResult(testUpdate4.orderBy("id").limit(1).execute(), 1, testTbl4.getName(), 1, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 0, testUpdate4, 0, -1);
        assertPreparedStatementsStatusCounts(testSession, 12, 20, 12);
        testPreparedStatementsResetData();
        // J. Set limit reuse statement: 2nd execute -> prepare + execute.
        assertTestPreparedStatementsResult(testUpdate1.limit(2).execute(), 2, testTbl1.getName(), 100, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 1, testUpdate1, 1, 1);
        assertTestPreparedStatementsResult(testUpdate2.limit(2).execute(), 1, testTbl2.getName(), 1, 2, 3, 400);
        assertPreparedStatementsCountsAndId(testSession, 2, testUpdate2, 2, 1);
        assertTestPreparedStatementsResult(testupdate3.limit(2).execute(), 2, testTbl3.getName(), 100, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 3, testupdate3, 3, 1);
        assertTestPreparedStatementsResult(testUpdate4.limit(2).execute(), 1, testTbl4.getName(), 1, 200, 3, 4);
        assertPreparedStatementsCountsAndId(testSession, 4, testUpdate4, 4, 1);
        assertPreparedStatementsStatusCounts(testSession, 16, 24, 12);
        testPreparedStatementsResetData();
        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);
            testTbl1 = testSession.getDefaultSchema().getTable("testPrepareUpdate_1");
            testTbl2 = testSession.getDefaultSchema().getTable("testPrepareUpdate_2");
            testUpdate1 = testTbl1.update().where("true").set("ord", expr("ord * 10"));
            testUpdate2 = testTbl2.update().where("true").set("ord", expr("ord * 10"));
            // 1st execute -> don't prepare.
            assertTestPreparedStatementsResult(testUpdate1.execute(), 4, testTbl1.getName(), 10, 20, 30, 40);
            assertPreparedStatementsCountsAndId(testSession, 0, testUpdate1, 0, -1);
            assertTestPreparedStatementsResult(testUpdate2.execute(), 4, testTbl2.getName(), 10, 20, 30, 40);
            assertPreparedStatementsCountsAndId(testSession, 0, testUpdate2, 0, -1);
            assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
            testPreparedStatementsResetData();
            // 2nd execute -> prepare + execute.
            assertTestPreparedStatementsResult(testUpdate1.execute(), 4, testTbl1.getName(), 10, 20, 30, 40);
            assertPreparedStatementsCountsAndId(testSession, 1, testUpdate1, 1, 1);
            // Fails preparing, execute as non-prepared.
            assertTestPreparedStatementsResult(testUpdate2.execute(), 4, testTbl2.getName(), 10, 20, 30, 40);
            assertPreparedStatementsCountsAndId(testSession, 1, testUpdate2, 0, -1);
            // Failed prepare also counts.
            assertPreparedStatementsStatusCounts(testSession, 2, 1, 0);
            testPreparedStatementsResetData();
            // 3rd execute -> execute.
            assertTestPreparedStatementsResult(testUpdate1.execute(), 4, testTbl1.getName(), 10, 20, 30, 40);
            assertPreparedStatementsCountsAndId(testSession, 1, testUpdate1, 1, 2);
            // Execute as non-prepared.
            assertTestPreparedStatementsResult(testUpdate2.execute(), 4, testTbl2.getName(), 10, 20, 30, 40);
            assertPreparedStatementsCountsAndId(testSession, 1, testUpdate2, 0, -1);
            assertPreparedStatementsStatusCounts(testSession, 2, 2, 0);
            testPreparedStatementsResetData();
            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();
        }
    } finally {
        for (int i = 0; i < 4; i++) {
            sqlUpdate("DROP TABLE IF EXISTS testPrepareUpdate_" + (i + 1));
        }
    }
}
Also used : SessionFactory(com.mysql.cj.xdevapi.SessionFactory) UpdateStatement(com.mysql.cj.xdevapi.UpdateStatement) Table(com.mysql.cj.xdevapi.Table) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 84 with Session

use of com.mysql.cj.xdevapi.Session in project aws-mysql-jdbc by awslabs.

the class XProtocolAuthTest method testEmptyDatabaseMYSQL41.

/**
 * Bug#21680263 - NullPointerException When Try to connect without DB Name.
 */
@Test
public void testEmptyDatabaseMYSQL41() {
    assumeTrue(this.isSetForXTests, PropertyDefinitions.SYSP_testsuite_url_mysqlx + " must be set to run this test.");
    try {
        Session testSession = this.fact.getSession(this.baseUrl);
        testSession.sql("CREATE USER IF NOT EXISTS 'testPlainAuth'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'").execute();
        testSession.close();
        protocol.send(this.messageBuilder.buildMysql41AuthStart(), 0);
        byte[] salt = protocol.readAuthenticateContinue();
        protocol.send(this.messageBuilder.buildMysql41AuthContinue("testPlainAuth", "pwd", salt, null), 0);
        protocol.readAuthenticateOk();
    } catch (Throwable t) {
        throw t;
    } finally {
        Session testSession = this.fact.getSession(this.baseUrl);
        testSession.sql("DROP USER if exists testPlainAuth").execute();
        testSession.close();
    }
}
Also used : Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 85 with Session

use of com.mysql.cj.xdevapi.Session in project aws-mysql-jdbc by awslabs.

the class XProtocolAuthTest method testBasicSaslMysql41Auth.

@Test
public void testBasicSaslMysql41Auth() throws Exception {
    assumeTrue(this.isSetForXTests, PropertyDefinitions.SYSP_testsuite_url_mysqlx + " must be set to run this test.");
    try {
        Session testSession = this.fact.getSession(this.baseUrl);
        testSession.sql("CREATE USER IF NOT EXISTS 'testPlainAuth'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'").execute();
        testSession.sql("GRANT SELECT ON *.* TO 'testPlainAuth'@'%'").execute();
        testSession.close();
        protocol.send(this.messageBuilder.buildMysql41AuthStart(), 0);
        byte[] salt = protocol.readAuthenticateContinue();
        protocol.send(this.messageBuilder.buildMysql41AuthContinue("testPlainAuth", "pwd", salt, getTestDatabase()), 0);
        protocol.readAuthenticateOk();
    } catch (Throwable t) {
        throw t;
    } finally {
        Session testSession = this.fact.getSession(this.baseUrl);
        testSession.sql("DROP USER if exists testPlainAuth").execute();
        testSession.close();
    }
}
Also used : Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Aggregations

Session (com.mysql.cj.xdevapi.Session)85 Test (org.junit.jupiter.api.Test)79 JsonString (com.mysql.cj.xdevapi.JsonString)40 SessionFactory (com.mysql.cj.xdevapi.SessionFactory)39 CoreSession (com.mysql.cj.CoreSession)38 Collection (com.mysql.cj.xdevapi.Collection)33 Properties (java.util.Properties)29 ExecutionException (java.util.concurrent.ExecutionException)26 WrongArgumentException (com.mysql.cj.exceptions.WrongArgumentException)23 Schema (com.mysql.cj.xdevapi.Schema)22 DocResult (com.mysql.cj.xdevapi.DocResult)16 DbDoc (com.mysql.cj.xdevapi.DbDoc)15 SessionImpl (com.mysql.cj.xdevapi.SessionImpl)15 SqlResult (com.mysql.cj.xdevapi.SqlResult)15 Row (com.mysql.cj.xdevapi.Row)14 Client (com.mysql.cj.xdevapi.Client)11 ClientFactory (com.mysql.cj.xdevapi.ClientFactory)11 RowResult (com.mysql.cj.xdevapi.RowResult)10 Field (java.lang.reflect.Field)9 CJCommunicationsException (com.mysql.cj.exceptions.CJCommunicationsException)8