From 47a7ed4cfa8b5c257382a83ac8c7aa98a7e9644f Mon Sep 17 00:00:00 2001 From: Thiago Nunes Date: Tue, 26 Nov 2024 17:00:36 +1100 Subject: [PATCH 1/5] feat: allow for connection dialect --- google-cloud-spanner/pom.xml | 2 +- .../ClientSideStatementValueConverters.java | 3 ++ .../cloud/spanner/connection/Connection.java | 8 +++ .../spanner/connection/ConnectionImpl.java | 52 +++++++++++++++++-- .../connection/ConnectionProperties.java | 2 +- .../ConnectionStatementExecutor.java | 5 ++ .../ConnectionStatementExecutorImpl.java | 17 ++++++ .../spanner/connection/StatementResult.java | 2 + .../connection/PG_ClientSideStatements.json | 24 +++++++++ .../ConnectionStatementExecutorTest.java | 9 ++++ 10 files changed, 117 insertions(+), 7 deletions(-) diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 845e8bfeef..7f90e31c3a 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner - 6.81.2 + 6.81.2-SNAPSHOT jar Google Cloud Spanner https://github.com/googleapis/java-spanner diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ClientSideStatementValueConverters.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ClientSideStatementValueConverters.java index 09525d4fa2..399cdb6cb9 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ClientSideStatementValueConverters.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ClientSideStatementValueConverters.java @@ -757,6 +757,9 @@ static class DialectConverter implements ClientSideStatementValueConverter getParameterClass() { return Dialect.class; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/Connection.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/Connection.java index 547d2466e3..2461f77474 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/Connection.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/Connection.java @@ -1478,6 +1478,14 @@ default Dialect getDialect() { throw new UnsupportedOperationException("Not implemented"); } + default Dialect getConnectionDialect() { + throw new UnsupportedOperationException("Not implemented"); + } + + default void setConnectionDialect(Dialect dialect) { + throw new UnsupportedOperationException("Not implemented"); + } + /** The {@link DatabaseClient} that is used by this {@link Connection}. */ @InternalApi default DatabaseClient getDatabaseClient() { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java index 37dcd3f9aa..d90d7e9d1f 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java @@ -28,6 +28,7 @@ import static com.google.cloud.spanner.connection.ConnectionProperties.DATA_BOOST_ENABLED; import static com.google.cloud.spanner.connection.ConnectionProperties.DDL_IN_TRANSACTION_MODE; import static com.google.cloud.spanner.connection.ConnectionProperties.DELAY_TRANSACTION_START_UNTIL_FIRST_WRITE; +import static com.google.cloud.spanner.connection.ConnectionProperties.DIALECT; import static com.google.cloud.spanner.connection.ConnectionProperties.DIRECTED_READ; import static com.google.cloud.spanner.connection.ConnectionProperties.KEEP_TRANSACTION_ALIVE; import static com.google.cloud.spanner.connection.ConnectionProperties.MAX_COMMIT_DELAY; @@ -103,6 +104,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.Stack; import java.util.UUID; @@ -118,6 +120,7 @@ /** Implementation for {@link Connection}, the generic Spanner connection API (not JDBC). */ class ConnectionImpl implements Connection { + private static final String INSTRUMENTATION_SCOPE = "cloud.google.com/java"; private static final String SINGLE_USE_TRANSACTION = "SingleUseTransaction"; private static final String READ_ONLY_TRANSACTION = "ReadOnlyTransaction"; @@ -160,6 +163,7 @@ class ConnectionImpl implements Connection { private static final ParsedStatement RELEASE_STATEMENT = AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) .parse(Statement.of("RELEASE s1")); + public static final String GOOGLESQL_DIALECT_HINT = "/* GOOGLESQL */ "; /** * Exception that is used to register the stacktrace of the code that opened a {@link Connection}. @@ -383,7 +387,10 @@ private DdlClient createDdlClient() { private AbstractStatementParser getStatementParser() { if (this.statementParser == null) { - this.statementParser = AbstractStatementParser.getInstance(dbClient.getDialect()); + Dialect dbDialect = dbClient.getDialect(); + Dialect connDialect = this.getConnectionPropertyValue(DIALECT); + Dialect parserDialect = Optional.ofNullable(connDialect).orElse(dbDialect); + this.statementParser = AbstractStatementParser.getInstance(parserDialect); } return this.statementParser; } @@ -527,6 +534,27 @@ public Dialect getDialect() { return dbClient.getDialect(); } + @Override + public Dialect getConnectionDialect() { + return Optional.ofNullable(getConnectionPropertyValue(DIALECT)) + .orElse(getDialect()); + } + + @Override + public void setConnectionDialect(Dialect dialect) { + ConnectionPreconditions.checkState(!isClosed(), CLOSED_ERROR_MSG); + ConnectionPreconditions.checkState(!isBatchActive(), "Cannot set dialect while in a batch"); + ConnectionPreconditions.checkState( + !isTransactionStarted(), "Cannot set dialect while a transaction is active"); + ConnectionPreconditions.checkState( + !(isAutocommit() && isInTransaction()), + "Cannot set dialect while in a temporary transaction"); + ConnectionPreconditions.checkState( + !transactionBeginMarked, "Cannot set dialect when a transaction has begun"); + setConnectionPropertyValue(DIALECT, dialect); + clearLastTransactionAndSetDefaultTransactionOptions(); + } + @Override public DatabaseClient getDatabaseClient() { return dbClient; @@ -1576,6 +1604,16 @@ public PartitionedQueryResultSet runPartitionedQuery( return new MergedResultSet(this, partitionIds, getMaxPartitionedParallelism()); } + // FIXME: This is added on all GoogleSQL dialect queries at the moment. This is only necessary for + // PostgreSQL database queries with GoogleSQL dialect override. + private Statement addDialectHintIfRequired(Statement stmt) { + Dialect connDialect = getConnectionPropertyValue(DIALECT); + if (connDialect == Dialect.GOOGLE_STANDARD_SQL) { + return stmt.toBuilder().replace(GOOGLESQL_DIALECT_HINT + stmt.getSql()).build(); + } + return stmt; + } + /** * Parses the given statement as a query and executes it. Throws a {@link SpannerException} if the * statement is not a query. @@ -1585,7 +1623,8 @@ private ResultSet parseAndExecuteQuery( Preconditions.checkNotNull(query); Preconditions.checkNotNull(analyzeMode); ConnectionPreconditions.checkState(!isClosed(), CLOSED_ERROR_MSG); - ParsedStatement parsedStatement = getStatementParser().parse(query, buildQueryOptions()); + Statement updatedQuery = addDialectHintIfRequired(query); + ParsedStatement parsedStatement = getStatementParser().parse(updatedQuery, buildQueryOptions()); if (parsedStatement.isQuery() || parsedStatement.isUpdate()) { switch (parsedStatement.getType()) { case CLIENT_SIDE: @@ -1624,7 +1663,8 @@ private AsyncResultSet parseAndExecuteQueryAsync( CallType callType, Statement query, AnalyzeMode analyzeMode, QueryOption... options) { Preconditions.checkNotNull(query); ConnectionPreconditions.checkState(!isClosed(), CLOSED_ERROR_MSG); - ParsedStatement parsedStatement = getStatementParser().parse(query, buildQueryOptions()); + Statement updatedQuery = addDialectHintIfRequired(query); + ParsedStatement parsedStatement = getStatementParser().parse(updatedQuery, buildQueryOptions()); if (parsedStatement.isQuery() || parsedStatement.isUpdate()) { switch (parsedStatement.getType()) { case CLIENT_SIDE: @@ -1678,7 +1718,8 @@ private boolean isInternalMetadataQuery(QueryOption... options) { public long executeUpdate(Statement update) { Preconditions.checkNotNull(update); ConnectionPreconditions.checkState(!isClosed(), CLOSED_ERROR_MSG); - ParsedStatement parsedStatement = getStatementParser().parse(update); + Statement updatedQuery = addDialectHintIfRequired(update); + ParsedStatement parsedStatement = getStatementParser().parse(updatedQuery); if (parsedStatement.isUpdate()) { switch (parsedStatement.getType()) { case UPDATE: @@ -1706,7 +1747,8 @@ public long executeUpdate(Statement update) { public ApiFuture executeUpdateAsync(Statement update) { Preconditions.checkNotNull(update); ConnectionPreconditions.checkState(!isClosed(), CLOSED_ERROR_MSG); - ParsedStatement parsedStatement = getStatementParser().parse(update); + Statement updatedQuery = addDialectHintIfRequired(update); + ParsedStatement parsedStatement = getStatementParser().parse(updatedQuery); if (parsedStatement.isUpdate()) { switch (parsedStatement.getType()) { case UPDATE: diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java index 0ca9b7256e..846fd7c3b3 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java @@ -225,7 +225,7 @@ class ConnectionProperties { create( DIALECT_PROPERTY_NAME, "Sets the dialect to use for new databases that are created by this connection.", - Dialect.GOOGLE_STANDARD_SQL, + null, DialectConverter.INSTANCE, Context.STARTUP); static final ConnectionProperty TRACK_SESSION_LEAKS = diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutor.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutor.java index 48f79118fe..13419866e8 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutor.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutor.java @@ -16,6 +16,7 @@ package com.google.cloud.spanner.connection; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.Options.RpcPriority; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; @@ -44,6 +45,10 @@ interface ConnectionStatementExecutor { StatementResult statementShowReadOnly(); + StatementResult statementSetDialect(Dialect dialect); + + StatementResult statementShowDialect(); + StatementResult statementSetRetryAbortsInternally(Boolean retryAbortsInternally); StatementResult statementShowRetryAbortsInternally(); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutorImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutorImpl.java index 9b28ee7503..ceb0d16803 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutorImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutorImpl.java @@ -32,6 +32,7 @@ import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_DATA_BOOST_ENABLED; import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_DEFAULT_TRANSACTION_ISOLATION; import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_DELAY_TRANSACTION_START_UNTIL_FIRST_WRITE; +import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_DIALECT; import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_DIRECTED_READ; import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_EXCLUDE_TXN_FROM_CHANGE_STREAMS; import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_KEEP_TRANSACTION_ALIVE; @@ -62,6 +63,7 @@ import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_COMMIT_TIMESTAMP; import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_DATA_BOOST_ENABLED; import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_DELAY_TRANSACTION_START_UNTIL_FIRST_WRITE; +import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_DIALECT; import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_DIRECTED_READ; import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_EXCLUDE_TXN_FROM_CHANGE_STREAMS; import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_KEEP_TRANSACTION_ALIVE; @@ -180,6 +182,21 @@ public StatementResult statementShowReadOnly() { SHOW_READONLY); } + @Override + public StatementResult statementSetDialect(Dialect dialect) { + Preconditions.checkNotNull(dialect); + getConnection().setConnectionDialect(dialect); + return noResult(SET_DIALECT); + } + + @Override + public StatementResult statementShowDialect() { + return StatementResultImpl.resultSet( + String.format("%sDIALECT", getNamespace(connection.getDialect())), + getConnection().getConnectionDialect(), + SHOW_DIALECT); + } + @Override public StatementResult statementSetRetryAbortsInternally(Boolean retryAbortsInternally) { Preconditions.checkNotNull(retryAbortsInternally); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementResult.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementResult.java index bd364ed522..63b8b649fb 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementResult.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementResult.java @@ -52,6 +52,8 @@ enum ClientSideStatementType { SET_AUTOCOMMIT, SHOW_READONLY, SET_READONLY, + SHOW_DIALECT, + SET_DIALECT, SHOW_RETRY_ABORTS_INTERNALLY, SET_RETRY_ABORTS_INTERNALLY, SHOW_AUTOCOMMIT_DML_MODE, diff --git a/google-cloud-spanner/src/main/resources/com/google/cloud/spanner/connection/PG_ClientSideStatements.json b/google-cloud-spanner/src/main/resources/com/google/cloud/spanner/connection/PG_ClientSideStatements.json index afb5b4a385..c6e31fb262 100644 --- a/google-cloud-spanner/src/main/resources/com/google/cloud/spanner/connection/PG_ClientSideStatements.json +++ b/google-cloud-spanner/src/main/resources/com/google/cloud/spanner/connection/PG_ClientSideStatements.json @@ -19,6 +19,15 @@ "method": "statementShowReadOnly", "exampleStatements": ["show spanner.readonly","show variable spanner.readonly"] }, + { + "name": "SHOW [VARIABLE] SPANNER.DIALECT", + "executorName": "ClientSideStatementNoParamExecutor", + "resultType": "RESULT_SET", + "statementType": "SHOW_DIALECT", + "regex": "(?is)\\A\\s*show\\s+(?:variable\\s+)?spanner\\.dialect\\s*\\z", + "method": "statementShowDialect", + "exampleStatements": ["show spanner.dialect","show variable spanner.dialect"] + }, { "name": "SHOW [VARIABLE] SPANNER.RETRY_ABORTS_INTERNALLY", "executorName": "ClientSideStatementNoParamExecutor", @@ -403,6 +412,21 @@ "converterName": "ClientSideStatementValueConverters$BooleanConverter" } }, + { + "name": "SET SPANNER.DIALECT =|TO GOOGLE_STANDARD_SQL|POSTGRESQL", + "executorName": "ClientSideStatementSetExecutor", + "resultType": "NO_RESULT", + "statementType": "SET_DIALECT", + "regex": "(?is)\\A\\s*set\\s+spanner\\.dialect(?:\\s*=\\s*|\\s+to\\s+)(.*)\\z", + "method": "statementSetDialect", + "exampleStatements": ["set spanner.dialect = GOOGLE_STANDARD_SQL", "set spanner.dialect = POSTGRESQL"], + "setStatement": { + "propertyName": "SPANNER.DIALECT", + "separator": "(?:=|\\s+TO\\s+)", + "allowedValues": "(GOOGLE_STANDARD_SQL|POSTGRESQL)", + "converterName": "ClientSideStatementValueConverters$DialectConverter" + } + }, { "name": "SET SPANNER.RETRY_ABORTS_INTERNALLY =|TO TRUE|FALSE", "executorName": "ClientSideStatementSetExecutor", diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementExecutorTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementExecutorTest.java index 3a5aa1e6d8..9038598fad 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementExecutorTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementExecutorTest.java @@ -33,6 +33,7 @@ import com.google.cloud.spanner.connection.PgTransactionMode.IsolationLevel; import java.time.Duration; import java.util.concurrent.TimeUnit; +import org.apache.commons.math3.stat.inference.GTest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -126,6 +127,14 @@ public void testStatementGetReadTimestamp() { verify(connection).getReadTimestampOrNull(); } + @Test + public void testStatementGetConnectionDialect() { + subject.statementSetDialect(Dialect.GOOGLE_STANDARD_SQL); + when(connection.getConnectionDialect()).thenReturn(Dialect.GOOGLE_STANDARD_SQL); + subject.statementShowDialect(); + verify(connection).getConnectionDialect(); + } + @Test public void testStatementGetStatementTimeout() { subject.statementSetStatementTimeout(Duration.ofSeconds(1L)); From 6118ac153ba494d59a396b3b46ff9bd848714ee0 Mon Sep 17 00:00:00 2001 From: Thiago Nunes Date: Wed, 27 Nov 2024 09:30:02 +1100 Subject: [PATCH 2/5] fix: clirr violations --- google-cloud-spanner/clirr-ignored-differences.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/google-cloud-spanner/clirr-ignored-differences.xml b/google-cloud-spanner/clirr-ignored-differences.xml index ec13415790..147f5503a6 100644 --- a/google-cloud-spanner/clirr-ignored-differences.xml +++ b/google-cloud-spanner/clirr-ignored-differences.xml @@ -790,5 +790,15 @@ com/google/cloud/spanner/connection/Connection boolean isAutoBatchDmlUpdateCountVerification() - + + 7012 + com/google/cloud/spanner/connection/Connection + com.google.cloud.spanner.Dialect getConnectionDialect() + + + 7012 + com/google/cloud/spanner/connection/Connection + void setConnectionDialect(com.google.cloud.spanner.Dialect) + + From f5c478e6d789274da68b797298d3f3250e50d449 Mon Sep 17 00:00:00 2001 From: Thiago Nunes Date: Wed, 27 Nov 2024 09:53:34 +1100 Subject: [PATCH 3/5] feat: set dialect context as user --- .../google/cloud/spanner/connection/ConnectionProperties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java index 846fd7c3b3..50a244121f 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java @@ -227,7 +227,7 @@ class ConnectionProperties { "Sets the dialect to use for new databases that are created by this connection.", null, DialectConverter.INSTANCE, - Context.STARTUP); + Context.USER); static final ConnectionProperty TRACK_SESSION_LEAKS = create( TRACK_SESSION_LEAKS_PROPERTY_NAME, From 10caa6840dca622b87fbd35d8a14a097bd4fe2a7 Mon Sep 17 00:00:00 2001 From: Thiago Nunes Date: Wed, 27 Nov 2024 11:57:40 +1100 Subject: [PATCH 4/5] feat: adds dialect option --- .../cloud/spanner/AbstractReadContext.java | 7 ++++- .../com/google/cloud/spanner/Options.java | 31 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractReadContext.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractReadContext.java index cecf462bd2..509c7cbc2b 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractReadContext.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractReadContext.java @@ -673,9 +673,14 @@ RequestOptions buildRequestOptions(Options options) { ExecuteSqlRequest.Builder getExecuteSqlRequestBuilder( Statement statement, QueryMode queryMode, Options options, boolean withTransactionSelector) { + String sql = statement.getSql(); + // FIXME: This should be a request / query option parameter instead + if (options.hasDialect() && options.dialect() == Dialect.GOOGLE_STANDARD_SQL) { + sql = "/* GOOGLESQL */ " + sql; + } ExecuteSqlRequest.Builder builder = ExecuteSqlRequest.newBuilder() - .setSql(statement.getSql()) + .setSql(sql) .setQueryMode(queryMode) .setSession(session.getName()); addParameters(builder, statement.getParameters()); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java index 9c3257586f..35f71dc6e4 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java @@ -184,6 +184,10 @@ public static ReadQueryUpdateTransactionOption priority(RpcPriority priority) { return new PriorityOption(priority); } + public static ReadQueryUpdateTransactionOption dialect(Dialect dialect) { + return new DialectOption(dialect); + } + public static TransactionOption maxCommitDelay(Duration maxCommitDelay) { Preconditions.checkArgument(!maxCommitDelay.isNegative(), "maxCommitDelay should be positive"); return new MaxCommitDelayOption(maxCommitDelay); @@ -377,6 +381,20 @@ void appendToOptions(Options options) { } } + static final class DialectOption extends InternalOption + implements ReadQueryUpdateTransactionOption { + private final Dialect dialect; + + DialectOption(Dialect dialect) { + this.dialect = dialect; + } + + @Override + void appendToOptions(Options options) { + options.dialect = dialect; + } + } + static final class TagOption extends InternalOption implements ReadQueryUpdateTransactionOption { private final String tag; @@ -460,6 +478,7 @@ void appendToOptions(Options options) { private String pageToken; private String filter; private RpcPriority priority; + private Dialect dialect; private String tag; private String etag; private Boolean validateOnly; @@ -541,6 +560,14 @@ Priority priority() { return priority == null ? null : priority.proto; } + boolean hasDialect() { + return dialect != null; + } + + Dialect dialect() { + return dialect; + } + boolean hasTag() { return tag != null; } @@ -693,6 +720,7 @@ public boolean equals(Object o) { && Objects.equals(pageToken(), that.pageToken()) && Objects.equals(filter(), that.filter()) && Objects.equals(priority(), that.priority()) + && Objects.equals(dialect(), that.dialect()) && Objects.equals(tag(), that.tag()) && Objects.equals(etag(), that.etag()) && Objects.equals(validateOnly(), that.validateOnly()) @@ -760,6 +788,9 @@ public int hashCode() { if (orderBy != null) { result = 31 * result + orderBy.hashCode(); } + if (dialect != null) { + result = 31 * result + dialect.hashCode(); + } return result; } From 2eb40818d23f78b22301732267cc6bab4ea1400d Mon Sep 17 00:00:00 2001 From: Thiago Nunes Date: Wed, 27 Nov 2024 13:26:31 +1100 Subject: [PATCH 5/5] fix: update connection dialect options --- .../cloud/spanner/connection/ConnectionImpl.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java index d90d7e9d1f..e8a4e3c0f6 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionImpl.java @@ -485,6 +485,7 @@ private void reset(Context context, boolean inTransaction) { this.connectionState.resetValue(OPTIMIZER_VERSION, context, inTransaction); this.connectionState.resetValue(OPTIMIZER_STATISTICS_PACKAGE, context, inTransaction); this.connectionState.resetValue(RPC_PRIORITY, context, inTransaction); + this.connectionState.resetValue(DIALECT, context, inTransaction); this.connectionState.resetValue(DDL_IN_TRANSACTION_MODE, context, inTransaction); this.connectionState.resetValue(RETURN_COMMIT_STATS, context, inTransaction); this.connectionState.resetValue( @@ -1897,6 +1898,9 @@ private QueryOption[] mergeQueryStatementTag(QueryOption... options) { private QueryOption[] mergeQueryRequestOptions( ParsedStatement parsedStatement, QueryOption... options) { + if (getConnectionPropertyValue(DIALECT) != null) { + options = appendQueryOption(options, Options.dialect(getConnectionPropertyValue(DIALECT))); + } if (getConnectionPropertyValue(RPC_PRIORITY) != null) { options = appendQueryOption(options, Options.priority(getConnectionPropertyValue(RPC_PRIORITY))); @@ -1945,6 +1949,14 @@ private UpdateOption[] mergeUpdateRequestOptions(UpdateOption... options) { options[options.length - 1] = Options.priority(getConnectionPropertyValue(RPC_PRIORITY)); } } + if (getConnectionPropertyValue(DIALECT) != null) { + if (options == null ||options.length == 0) { + options = new UpdateOption[] {Options.dialect(getConnectionPropertyValue(DIALECT))}; + } else { + options = Arrays.copyOf(options, options.length + 1); + options[options.length - 1] = Options.dialect(getConnectionPropertyValue(DIALECT)); + } + } return options; }