diff --git a/pom.xml b/pom.xml index 14ecefb23..3abd02ea9 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 google-cloud-spanner-jdbc - 2.17.1-SNAPSHOT + 2.17.2-SNAPSHOT jar Google Cloud Spanner JDBC https://github.com/googleapis/java-spanner-jdbc diff --git a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcStatement.java b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcStatement.java index d12678bf2..2c8a923e4 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcStatement.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcStatement.java @@ -57,6 +57,25 @@ public JdbcConnection getConnection() { return connection; } + String maybeAddWhereClause(String sql) { + String lowerCaseSql = sql.toLowerCase(); + if (lowerCaseSql.startsWith("delete") || lowerCaseSql.startsWith("update")) { + if (!lowerCaseSql.contains(" where ")) { + return sql + " where true"; + } + } + return sql; + } + + boolean isAllowedDdlStatementInTransaction(String sql) throws SQLException { + if (!getConnection().getAutoCommit() && getConnection().getParser().isDdlStatement(sql)) { + if (!getConnection().isTransactionStarted()) { + return true; + } + } + return false; + } + private Options.QueryOption[] getQueryOptions(QueryOption... options) throws SQLException { QueryOption[] res = options == null ? new QueryOption[0] : options; if (getFetchSize() > 0) { diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatement.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatement.java index 9ebbc98f5..ae29ea071 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatement.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcPreparedStatement.java @@ -47,7 +47,7 @@ class JdbcPreparedStatement extends AbstractJdbcPreparedStatement JdbcConnection connection, String sql, ImmutableList generatedKeysColumns) throws SQLException { super(connection); - this.sql = sql; + this.sql = maybeAddWhereClause(sql); try { // The PostgreSQL parser allows comments to be present in the SQL string that is used to parse // the query parameters. diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcStatement.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcStatement.java index 19b325654..655190c57 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcStatement.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcStatement.java @@ -103,7 +103,7 @@ public long executeLargeUpdate(String sql) throws SQLException { private long executeLargeUpdate(String sql, ImmutableList generatedKeysColumns) throws SQLException { - return executeLargeUpdate(Statement.of(sql), generatedKeysColumns); + return executeLargeUpdate(Statement.of(maybeAddWhereClause(sql)), generatedKeysColumns); } protected long executeLargeUpdate(Statement statement, ImmutableList generatedKeysColumns) @@ -112,7 +112,19 @@ protected long executeLargeUpdate(Statement statement, ImmutableList gen checkClosed(); Statement statementWithReturningClause = addReturningToStatement(statement, generatedKeysColumns); - StatementResult result = execute(statementWithReturningClause); + boolean allowedDdlStatementInTransaction = + isAllowedDdlStatementInTransaction(statement.getSql()); + StatementResult result; + if (allowedDdlStatementInTransaction) { + getConnection().setAutoCommit(true); + } + try { + result = execute(statementWithReturningClause); + } finally { + if (allowedDdlStatementInTransaction) { + getConnection().setAutoCommit(false); + } + } switch (result.getResultType()) { case RESULT_SET: if (generatedKeysColumns.isEmpty()) { @@ -256,7 +268,7 @@ String quoteColumn(String column) { @Override public boolean execute(String sql) throws SQLException { - return executeStatement(Statement.of(sql), NO_GENERATED_KEY_COLUMNS); + return executeStatement(Statement.of(maybeAddWhereClause(sql)), NO_GENERATED_KEY_COLUMNS); } boolean executeStatement(Statement statement, ImmutableList generatedKeysColumns)