Search in sources :

Example 11 with XProtocolError

use of com.mysql.cj.protocol.x.XProtocolError in project aws-mysql-jdbc by awslabs.

the class SchemaTest method testCreateCollection.

@Test
public void testCreateCollection() {
    String collName = "testCreateCollection";
    try {
        dropCollection(collName);
        Collection coll = this.schema.createCollection(collName);
        try {
            this.schema.createCollection(collName);
            fail("Exception should be thrown trying to create a collection that already exists");
        } catch (XProtocolError ex) {
            // expected
            assertEquals(MysqlErrorNumbers.ER_TABLE_EXISTS_ERROR, ex.getErrorCode());
        }
        try {
            this.schema.createCollection(collName, false);
            fail("Exception should be thrown trying to create a collection that already exists");
        } catch (XProtocolError ex) {
            // expected
            assertEquals(MysqlErrorNumbers.ER_TABLE_EXISTS_ERROR, ex.getErrorCode());
        }
        Collection coll2 = this.schema.createCollection(collName, true);
        assertEquals(coll, coll2);
    } finally {
        dropCollection(collName);
    }
}
Also used : XProtocolError(com.mysql.cj.protocol.x.XProtocolError) Collection(com.mysql.cj.xdevapi.Collection) Test(org.junit.jupiter.api.Test)

Example 12 with XProtocolError

use of com.mysql.cj.protocol.x.XProtocolError 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 13 with XProtocolError

use of com.mysql.cj.protocol.x.XProtocolError in project aws-mysql-jdbc by awslabs.

the class InternalXBaseTestCase method createTempTestCollection.

/**
 * Create a temporary collection for testing.
 *
 * @param protocol
 *
 * @return the temporary collection name
 */
public String createTempTestCollection(XProtocol protocol) {
    String collName = "protocol_test_collection";
    XMessageBuilder messageBuilder = (XMessageBuilder) protocol.getMessageBuilder();
    try {
        protocol.send(messageBuilder.buildDropCollection(getTestDatabase(), collName), 0);
        protocol.readQueryResult(new StatementExecuteOkBuilder());
    } catch (XProtocolError err) {
    // ignore
    }
    protocol.send(messageBuilder.buildCreateCollection(getTestDatabase(), collName), 0);
    protocol.readQueryResult(new StatementExecuteOkBuilder());
    return collName;
}
Also used : XMessageBuilder(com.mysql.cj.protocol.x.XMessageBuilder) StatementExecuteOkBuilder(com.mysql.cj.protocol.x.StatementExecuteOkBuilder) XProtocolError(com.mysql.cj.protocol.x.XProtocolError)

Example 14 with XProtocolError

use of com.mysql.cj.protocol.x.XProtocolError in project aws-mysql-jdbc by awslabs.

the class InternalXBaseTestCase method createTestSchema.

public void createTestSchema(XProtocol protocol, String schemaName) {
    XMessageBuilder messageBuilder = (XMessageBuilder) protocol.getMessageBuilder();
    try {
        StringBuilder stmtString = new StringBuilder("CREATE DATABASE ");
        stmtString.append(StringUtils.quoteIdentifier(schemaName, true));
        protocol.send(messageBuilder.buildSqlStatement(stmtString.toString()), 0);
        protocol.readQueryResult(new StatementExecuteOkBuilder());
    } catch (XProtocolError ex) {
        if (ex.getErrorCode() != MysqlErrorNumbers.ER_DB_CREATE_EXISTS) {
            throw ex;
        }
    }
}
Also used : XMessageBuilder(com.mysql.cj.protocol.x.XMessageBuilder) StatementExecuteOkBuilder(com.mysql.cj.protocol.x.StatementExecuteOkBuilder) XProtocolError(com.mysql.cj.protocol.x.XProtocolError)

Example 15 with XProtocolError

use of com.mysql.cj.protocol.x.XProtocolError in project aws-mysql-jdbc by awslabs.

the class MysqlxSessionTest method testCreateDropCollection.

@Test
public void testCreateDropCollection() {
    assumeTrue(this.isSetForXTests, PropertyDefinitions.SYSP_testsuite_url_mysqlx + " must be set to run this test.");
    String collName = "toBeCreatedAndDropped";
    XMessageBuilder builder = (XMessageBuilder) this.session.<XMessage>getMessageBuilder();
    try {
        this.session.query(builder.buildDropCollection(getTestDatabase(), collName), new UpdateResultBuilder<>());
    } catch (XProtocolError e) {
        if (e.getErrorCode() != MysqlErrorNumbers.ER_BAD_TABLE_ERROR) {
            throw e;
        }
    }
    assertFalse(this.session.getDataStoreMetadata().tableExists(getTestDatabase(), collName));
    this.session.query(builder.buildCreateCollection(getTestDatabase(), collName), new UpdateResultBuilder<>());
    assertTrue(this.session.getDataStoreMetadata().tableExists(getTestDatabase(), collName));
    this.session.query(builder.buildDropCollection(getTestDatabase(), collName), new UpdateResultBuilder<>());
    assertFalse(this.session.getDataStoreMetadata().tableExists(getTestDatabase(), collName));
    this.session.query(builder.buildCreateCollection(getTestDatabase(), collName), new UpdateResultBuilder<>());
    assertTrue(this.session.getDataStoreMetadata().tableExists(getTestDatabase(), collName));
    this.session.query(builder.buildDropCollection(getTestDatabase(), collName), new UpdateResultBuilder<>());
    assertFalse(this.session.getDataStoreMetadata().tableExists(getTestDatabase(), collName));
    this.session.query(builder.buildCreateCollection(getTestDatabase(), collName), new UpdateResultBuilder<>());
    assertTrue(this.session.getDataStoreMetadata().tableExists(getTestDatabase(), collName));
    this.session.query(builder.buildDropCollection(getTestDatabase(), collName), new UpdateResultBuilder<>());
    assertFalse(this.session.getDataStoreMetadata().tableExists(getTestDatabase(), collName));
}
Also used : XMessageBuilder(com.mysql.cj.protocol.x.XMessageBuilder) XProtocolError(com.mysql.cj.protocol.x.XProtocolError) Test(org.junit.jupiter.api.Test)

Aggregations

XProtocolError (com.mysql.cj.protocol.x.XProtocolError)15 Test (org.junit.jupiter.api.Test)12 XMessageBuilder (com.mysql.cj.protocol.x.XMessageBuilder)6 DocResult (com.mysql.cj.xdevapi.DocResult)6 StatementExecuteOkBuilder (com.mysql.cj.protocol.x.StatementExecuteOkBuilder)4 JsonString (com.mysql.cj.xdevapi.JsonString)4 ArrayList (java.util.ArrayList)4 ExecutionException (java.util.concurrent.ExecutionException)4 Collection (com.mysql.cj.xdevapi.Collection)3 List (java.util.List)3 Function (java.util.function.Function)3 Collectors (java.util.stream.Collectors)3 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)3 Assertions.assertFalse (org.junit.jupiter.api.Assertions.assertFalse)3 ServerVersion (com.mysql.cj.ServerVersion)2 MysqlErrorNumbers (com.mysql.cj.exceptions.MysqlErrorNumbers)2 WrongArgumentException (com.mysql.cj.exceptions.WrongArgumentException)2 XMessage (com.mysql.cj.protocol.x.XMessage)2 DbDoc (com.mysql.cj.xdevapi.DbDoc)2 DbDocImpl (com.mysql.cj.xdevapi.DbDocImpl)2