diff --git a/src/test/java/com/google/cloud/spanner/jdbc/ExecuteMockServerTest.java b/src/test/java/com/google/cloud/spanner/jdbc/ExecuteMockServerTest.java index d7d72f76f..0da181444 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/ExecuteMockServerTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/ExecuteMockServerTest.java @@ -38,6 +38,7 @@ import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import com.google.spanner.v1.CommitRequest; import com.google.spanner.v1.ExecuteBatchDmlRequest; +import com.google.spanner.v1.ExecuteSqlRequest; import com.google.spanner.v1.ResultSetMetadata; import com.google.spanner.v1.ResultSetStats; import com.google.spanner.v1.StructType; @@ -66,6 +67,8 @@ */ @RunWith(Parameterized.class) public class ExecuteMockServerTest extends AbstractMockServerTest { + private static final IllegalStateException REQUEST_NOT_FOUND = + new IllegalStateException("request not found"); private static Dialect currentDialect; @Parameters(name = "dialect = {0}") @@ -219,9 +222,27 @@ public void testStatementExecuteQuery() throws SQLException { try (ResultSet resultSet = statement.executeQuery(query)) { verifyResultSet(resultSet); } + ExecuteSqlRequest request = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).stream() + .filter(r -> r.getSql().equals(query)) + .findAny() + .orElseThrow(() -> REQUEST_NOT_FOUND); + assertTrue(request.getTransaction().hasSingleUse()); + assertTrue(request.getTransaction().getSingleUse().hasReadOnly()); + assertFalse(request.getLastStatement()); + try (ResultSet resultSet = statement.executeQuery(dmlReturning)) { verifyResultSet(resultSet); } + request = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).stream() + .filter(r -> r.getSql().equals(dmlReturning)) + .findAny() + .orElseThrow(() -> REQUEST_NOT_FOUND); + assertTrue(request.getTransaction().hasBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertTrue(request.getLastStatement()); + try (ResultSet resultSet = statement.executeQuery(clientSideQuery)) { verifyClientSideResultSet(resultSet); } @@ -237,6 +258,15 @@ public void testStatementExecuteUpdate() throws SQLException { try (Connection connection = createJdbcConnection(); Statement statement = connection.createStatement()) { assertEquals(1, statement.executeUpdate(dml)); + ExecuteSqlRequest request = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).stream() + .filter(r -> r.getSql().equals(dml)) + .findAny() + .orElseThrow(() -> REQUEST_NOT_FOUND); + assertTrue(request.getTransaction().hasBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertTrue(request.getLastStatement()); + assertEquals(0, statement.executeUpdate(DDL)); connection.setAutoCommit(false); @@ -256,6 +286,14 @@ public void testStatementExecuteUpdateReturnGeneratedKeys() throws SQLException Statement statement = connection.createStatement()) { // TODO: Add tests for RETURN_GENERATED_KEYS when that is supported. assertEquals(1, statement.executeUpdate(dml, Statement.NO_GENERATED_KEYS)); + ExecuteSqlRequest request = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).stream() + .findAny() + .orElseThrow(() -> REQUEST_NOT_FOUND); + assertTrue(request.getTransaction().hasBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertTrue(request.getLastStatement()); + assertEquals(0, statement.executeUpdate(DDL, Statement.NO_GENERATED_KEYS)); assertEquals(0, statement.executeUpdate(clientSideUpdate, Statement.NO_GENERATED_KEYS)); @@ -271,6 +309,14 @@ public void testStatementExecuteUpdateReturnColumnNames() throws SQLException { try (Connection connection = createJdbcConnection(); Statement statement = connection.createStatement()) { assertEquals(1, statement.executeUpdate(dml, new String[] {"id"})); + ExecuteSqlRequest request = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).stream() + .findAny() + .orElseThrow(() -> REQUEST_NOT_FOUND); + assertTrue(request.getTransaction().hasBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertTrue(request.getLastStatement()); + assertEquals(0, statement.executeUpdate(DDL, new String[] {"id"})); assertEquals(0, statement.executeUpdate(clientSideUpdate, new String[] {"id"})); @@ -289,6 +335,14 @@ public void testStatementExecuteUpdateReturnColumnIndexes() throws SQLException try (Connection connection = createJdbcConnection(); Statement statement = connection.createStatement()) { assertEquals(1, statement.executeUpdate(dml, new int[] {1})); + ExecuteSqlRequest request = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).stream() + .findAny() + .orElseThrow(() -> REQUEST_NOT_FOUND); + assertTrue(request.getTransaction().hasBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertTrue(request.getLastStatement()); + assertEquals(0, statement.executeUpdate(DDL, new int[] {1})); assertEquals(0, statement.executeUpdate(clientSideUpdate, new int[] {1})); verifyOverflow(() -> statement.executeUpdate(largeDml, new int[] {1})); @@ -303,6 +357,14 @@ public void testStatementLargeExecuteUpdate() throws SQLException { try (Connection connection = createJdbcConnection(); Statement statement = connection.createStatement()) { assertEquals(1L, statement.executeLargeUpdate(dml)); + ExecuteSqlRequest request = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).stream() + .findAny() + .orElseThrow(() -> REQUEST_NOT_FOUND); + assertTrue(request.getTransaction().hasBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertTrue(request.getLastStatement()); + assertEquals(0L, statement.executeLargeUpdate(DDL)); assertEquals(0L, statement.executeLargeUpdate(clientSideUpdate)); assertEquals(LARGE_UPDATE_COUNT, statement.executeLargeUpdate(largeDml)); @@ -318,6 +380,14 @@ public void testStatementExecuteLargeUpdateReturnGeneratedKeys() throws SQLExcep Statement statement = connection.createStatement()) { // TODO: Add tests for RETURN_GENERATED_KEYS when that is supported. assertEquals(1, statement.executeLargeUpdate(dml, Statement.NO_GENERATED_KEYS)); + ExecuteSqlRequest request = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).stream() + .findAny() + .orElseThrow(() -> REQUEST_NOT_FOUND); + assertTrue(request.getTransaction().hasBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertTrue(request.getLastStatement()); + assertEquals(0, statement.executeLargeUpdate(DDL, Statement.NO_GENERATED_KEYS)); assertEquals(0, statement.executeLargeUpdate(clientSideUpdate, Statement.NO_GENERATED_KEYS)); assertEquals( @@ -870,4 +940,102 @@ public void testExecuteAutoBatchDml() throws SQLException { assertEquals(3, request.getStatementsCount()); assertEquals(1, mockSpanner.countRequestsOfType(CommitRequest.class)); } + + @Test + public void testLastStatement_AutoCommit_Query() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + //noinspection EmptyTryBlock + try (ResultSet ignore = statement.executeQuery(query)) {} + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + assertFalse(mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0).getLastStatement()); + } + + @Test + public void testLastStatement_AutoCommit_Dml() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + statement.executeUpdate(dml); + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + assertTrue(mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0).getLastStatement()); + } + + @Test + public void testLastStatement_AutoCommit_DmlReturning() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + //noinspection EmptyTryBlock + try (ResultSet ignore = statement.executeQuery(dmlReturning)) {} + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + assertTrue(mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0).getLastStatement()); + } + + @Test + public void testLastStatement_AutoCommit_BatchDml() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + statement.addBatch(dml); + statement.addBatch(dml); + statement.executeBatch(); + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteBatchDmlRequest.class)); + assertTrue( + mockSpanner.getRequestsOfType(ExecuteBatchDmlRequest.class).get(0).getLastStatements()); + } + + @Test + public void testLastStatement_Transaction_Query() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + connection.setAutoCommit(false); + //noinspection EmptyTryBlock + try (ResultSet ignore = statement.executeQuery(query)) {} + connection.commit(); + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + assertFalse(mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0).getLastStatement()); + } + + @Test + public void testLastStatement_Transaction_Dml() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + connection.setAutoCommit(false); + statement.executeUpdate(dml); + connection.commit(); + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + assertFalse(mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0).getLastStatement()); + } + + @Test + public void testLastStatement_Transaction_DmlReturning() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + connection.setAutoCommit(false); + //noinspection EmptyTryBlock + try (ResultSet ignore = statement.executeQuery(dmlReturning)) {} + connection.commit(); + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + assertFalse(mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0).getLastStatement()); + } + + @Test + public void testLastStatement_Transaction_BatchDml() throws SQLException { + try (Connection connection = createJdbcConnection(); + Statement statement = connection.createStatement()) { + connection.setAutoCommit(false); + statement.addBatch(dml); + statement.addBatch(dml); + statement.executeBatch(); + connection.commit(); + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteBatchDmlRequest.class)); + assertFalse( + mockSpanner.getRequestsOfType(ExecuteBatchDmlRequest.class).get(0).getLastStatements()); + } }