From 5f156f2efdb4726679766b385d500a030c24e477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 10 Feb 2022 18:47:19 +0100 Subject: [PATCH] feat: PostgreSQL dialect databases (#1673) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: PostgreSQL dialect databases * 🦉 Updates from OwlBot See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * fix: add clirr differences * fix: do not join type names for every invocation * 🦉 Updates from OwlBot See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * fix: revert to showing column index * test: add parameterization for ITBatchReadTest * test: parameterize BatchReadTest and skip unsupported tests Co-authored-by: Owl Bot --- .../clirr-ignored-differences.xml | 13 + .../cloud/spanner/AbstractResultSet.java | 34 +- .../cloud/spanner/AbstractStructReader.java | 37 +- .../com/google/cloud/spanner/Database.java | 1 + .../spanner/DatabaseAdminClientImpl.java | 9 +- .../google/cloud/spanner/DatabaseInfo.java | 34 +- .../com/google/cloud/spanner/Dialect.java | 83 + .../com/google/cloud/spanner/Mutation.java | 4 +- .../google/cloud/spanner/SpannerOptions.java | 33 + .../java/com/google/cloud/spanner/Struct.java | 4 + .../java/com/google/cloud/spanner/Type.java | 66 +- .../java/com/google/cloud/spanner/Value.java | 159 + .../com/google/cloud/spanner/ValueBinder.java | 5 + .../connection/AbstractBaseUnitOfWork.java | 2 +- .../AbstractMultiUseTransaction.java | 2 +- ...rser.java => AbstractStatementParser.java} | 329 +- .../spanner/connection/ChecksumResultSet.java | 12 +- .../cloud/spanner/connection/Connection.java | 6 + .../spanner/connection/ConnectionImpl.java | 14 +- .../spanner/connection/ConnectionOptions.java | 72 +- .../cloud/spanner/connection/DdlBatch.java | 20 +- .../cloud/spanner/connection/DmlBatch.java | 4 +- .../spanner/connection/FailedBatchUpdate.java | 6 +- .../cloud/spanner/connection/FailedQuery.java | 2 +- .../spanner/connection/FailedUpdate.java | 2 +- .../connection/PostgreSQLStatementParser.java | 256 + .../connection/ReadOnlyTransaction.java | 2 +- .../connection/ReadWriteTransaction.java | 48 +- .../connection/RetriableBatchUpdate.java | 6 +- .../spanner/connection/RetriableUpdate.java | 2 +- .../connection/SingleUseTransaction.java | 18 +- .../cloud/spanner/connection/SpannerPool.java | 15 +- .../connection/SpannerStatementParser.java | 249 + .../StatementExecutionInterceptor.java | 2 +- .../spanner/connection/StatementExecutor.java | 2 +- .../cloud/spanner/connection/UnitOfWork.java | 2 +- .../cloud/spanner/spi/v1/GapicSpannerRpc.java | 34 +- .../spanner/testing/RemoteSpannerHelper.java | 32 +- .../AbstractStructReaderTypesTest.java | 14 + .../spanner/DatabaseAdminClientImplTest.java | 12 +- .../google/cloud/spanner/DatabaseTest.java | 82 +- .../com/google/cloud/spanner/DialectTest.java | 95 + .../cloud/spanner/MockSpannerServiceImpl.java | 131 +- .../google/cloud/spanner/MutationTest.java | 68 +- .../google/cloud/spanner/PgNumericTest.java | 372 + .../cloud/spanner/SpannerOptionsTest.java | 3 + .../com/google/cloud/spanner/StructTest.java | 27 + .../com/google/cloud/spanner/TypeTest.java | 95 +- .../google/cloud/spanner/ValueBinderTest.java | 11 + .../com/google/cloud/spanner/ValueTest.java | 182 + .../AbstractConnectionImplTest.java | 2 +- .../connection/AbstractSqlScriptTest.java | 57 + .../connection/AbstractSqlScriptVerifier.java | 13 +- .../connection/ClientSideStatementsTest.java | 29 +- .../ConnectionImplAutocommitReadOnlyTest.java | 2 +- ...ConnectionImplAutocommitReadWriteTest.java | 2 +- .../ConnectionImplGeneratedSqlScriptTest.java | 23 +- .../connection/ConnectionImplTest.java | 87 +- ...nnectionImplTransactionalReadOnlyTest.java | 2 +- ...nectionImplTransactionalReadWriteTest.java | 2 +- .../connection/ConnectionOptionsTest.java | 76 + ...nnectionStatementWithNoParametersTest.java | 23 +- ...nnectionStatementWithOneParameterTest.java | 23 +- .../spanner/connection/DdlBatchTest.java | 27 +- .../spanner/connection/DmlBatchTest.java | 11 +- .../connection/ITAbstractSpannerTest.java | 2 +- .../connection/ReadOnlyTransactionTest.java | 4 +- .../connection/ReadWriteTransactionTest.java | 4 +- .../SetReadOnlyStalenessSqlScriptTest.java | 23 +- .../SetStatementTimeoutSqlScriptTest.java | 23 +- .../connection/SingleUseTransactionTest.java | 4 +- .../spanner/connection/SqlScriptVerifier.java | 6 + .../connection/StatementParserTest.java | 978 +- .../connection/TestChannelProvider.java | 26 + .../spanner/it/DialectTestParameter.java | 50 + .../cloud/spanner/it/ITBatchReadTest.java | 143 +- .../google/cloud/spanner/it/ITDMLTest.java | 99 +- .../it/ITDatabaseAdminDialectAwareTest.java | 120 + .../cloud/spanner/it/ITDatabaseAdminTest.java | 73 +- .../cloud/spanner/it/ITLargeReadTest.java | 74 +- .../cloud/spanner/it/ITPgNumericTest.java | 472 + .../google/cloud/spanner/it/ITQueryTest.java | 361 +- .../google/cloud/spanner/it/ITReadTest.java | 123 +- .../cloud/spanner/it/ITResultSetGetValue.java | 226 +- .../spanner/it/ITTransactionManagerTest.java | 58 +- .../google/cloud/spanner/it/ITWriteTest.java | 126 +- .../cloud/spanner/it/slow/ITBackupTest.java | 11 + .../spanner/spi/v1/GapicSpannerRpcTest.java | 38 +- .../connection/ClientSideStatementsTest.sql | 1110 +- .../ConnectionImplGeneratedSqlScriptTest.sql | 10464 ++++++++-------- .../connection/PostgreSQLCommentsTest.sql | 187 + 91 files changed, 11073 insertions(+), 6824 deletions(-) create mode 100644 google-cloud-spanner/clirr-ignored-differences.xml create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/Dialect.java rename google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/{StatementParser.java => AbstractStatementParser.java} (57%) create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/PostgreSQLStatementParser.java create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerStatementParser.java create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/DialectTest.java create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/PgNumericTest.java create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptTest.java create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/TestChannelProvider.java create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/DialectTestParameter.java create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminDialectAwareTest.java create mode 100644 google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITPgNumericTest.java create mode 100644 google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/PostgreSQLCommentsTest.sql diff --git a/google-cloud-spanner/clirr-ignored-differences.xml b/google-cloud-spanner/clirr-ignored-differences.xml new file mode 100644 index 00000000000..c750b2a7f40 --- /dev/null +++ b/google-cloud-spanner/clirr-ignored-differences.xml @@ -0,0 +1,13 @@ + + + + + 7012 + com/google/cloud/spanner/connection/Connection + com.google.cloud.spanner.Dialect getDialect() + + + 8001 + com/google/cloud/spanner/connection/StatementParser + + diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java index 54bfc3f5453..6143386293d 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractResultSet.java @@ -375,6 +375,9 @@ private Object writeReplace() { case NUMERIC: builder.set(fieldName).to((BigDecimal) value); break; + case PG_NUMERIC: + builder.set(fieldName).to((String) value); + break; case STRING: builder.set(fieldName).to((String) value); break; @@ -391,7 +394,8 @@ private Object writeReplace() { builder.set(fieldName).to((Date) value); break; case ARRAY: - switch (fieldType.getArrayElementType().getCode()) { + final Type elementType = fieldType.getArrayElementType(); + switch (elementType.getCode()) { case BOOL: builder.set(fieldName).toBoolArray((Iterable) value); break; @@ -404,6 +408,9 @@ private Object writeReplace() { case NUMERIC: builder.set(fieldName).toNumericArray((Iterable) value); break; + case PG_NUMERIC: + builder.set(fieldName).toPgNumericArray((Iterable) value); + break; case STRING: builder.set(fieldName).toStringArray((Iterable) value); break; @@ -420,13 +427,10 @@ private Object writeReplace() { builder.set(fieldName).toDateArray((Iterable) value); break; case STRUCT: - builder - .set(fieldName) - .toStructArray(fieldType.getArrayElementType(), (Iterable) value); + builder.set(fieldName).toStructArray(elementType, (Iterable) value); break; default: - throw new AssertionError( - "Unhandled array type code: " + fieldType.getArrayElementType()); + throw new AssertionError("Unhandled array type code: " + elementType); } break; case STRUCT: @@ -484,7 +488,11 @@ private static Object decodeValue(Type fieldType, com.google.protobuf.Value prot case FLOAT64: return valueProtoToFloat64(proto); case NUMERIC: + checkType(fieldType, proto, KindCase.STRING_VALUE); return new BigDecimal(proto.getStringValue()); + case PG_NUMERIC: + checkType(fieldType, proto, KindCase.STRING_VALUE); + return proto.getStringValue(); case STRING: case JSON: checkType(fieldType, proto, KindCase.STRING_VALUE); @@ -549,6 +557,10 @@ static Object decodeArrayValue(Type elementType, ListValue listValue) { } return list; } + case PG_NUMERIC: + return Lists.transform( + listValue.getValuesList(), + input -> input.getKindCase() == KindCase.NULL_VALUE ? null : input.getStringValue()); case STRING: case JSON: return Lists.transform( @@ -695,6 +707,8 @@ protected Value getValueInternal(int columnIndex) { return Value.int64(isNull ? null : getLongInternal(columnIndex)); case NUMERIC: return Value.numeric(isNull ? null : getBigDecimalInternal(columnIndex)); + case PG_NUMERIC: + return Value.pgNumeric(isNull ? null : getStringInternal(columnIndex)); case FLOAT64: return Value.float64(isNull ? null : getDoubleInternal(columnIndex)); case STRING: @@ -708,13 +722,16 @@ protected Value getValueInternal(int columnIndex) { case STRUCT: return Value.struct(isNull ? null : getStructInternal(columnIndex)); case ARRAY: - switch (columnType.getArrayElementType().getCode()) { + final Type elementType = columnType.getArrayElementType(); + switch (elementType.getCode()) { case BOOL: return Value.boolArray(isNull ? null : getBooleanListInternal(columnIndex)); case INT64: return Value.int64Array(isNull ? null : getLongListInternal(columnIndex)); case NUMERIC: return Value.numericArray(isNull ? null : getBigDecimalListInternal(columnIndex)); + case PG_NUMERIC: + return Value.pgNumericArray(isNull ? null : getStringListInternal(columnIndex)); case FLOAT64: return Value.float64Array(isNull ? null : getDoubleListInternal(columnIndex)); case STRING: @@ -727,8 +744,7 @@ protected Value getValueInternal(int columnIndex) { return Value.dateArray(isNull ? null : getDateListInternal(columnIndex)); case STRUCT: return Value.structArray( - columnType.getArrayElementType(), - isNull ? null : getStructListInternal(columnIndex)); + elementType, isNull ? null : getStructListInternal(columnIndex)); default: throw new IllegalArgumentException( "Invalid array value type " + this.type.getArrayElementType()); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java index 185ab03eef6..d9038466a46 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractStructReader.java @@ -22,6 +22,7 @@ import com.google.cloud.Date; import com.google.cloud.Timestamp; import java.math.BigDecimal; +import java.util.Arrays; import java.util.List; /** @@ -159,14 +160,19 @@ public BigDecimal getBigDecimal(String columnName) { @Override public String getString(int columnIndex) { - checkNonNullOfType(columnIndex, Type.string(), columnIndex); + checkNonNullOfTypes( + columnIndex, + Arrays.asList(Type.string(), Type.pgNumeric()), + columnIndex, + "STRING, NUMERIC"); return getStringInternal(columnIndex); } @Override public String getString(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.string(), columnName); + checkNonNullOfTypes( + columnIndex, Arrays.asList(Type.string(), Type.pgNumeric()), columnName, "STRING, NUMERIC"); return getStringInternal(columnIndex); } @@ -327,14 +333,22 @@ public List getBigDecimalList(String columnName) { @Override public List getStringList(int columnIndex) { - checkNonNullOfType(columnIndex, Type.array(Type.string()), columnIndex); + checkNonNullOfTypes( + columnIndex, + Arrays.asList(Type.array(Type.string()), Type.array(Type.pgNumeric())), + columnIndex, + "ARRAY, ARRAY"); return getStringListInternal(columnIndex); } @Override public List getStringList(String columnName) { int columnIndex = getColumnIndex(columnName); - checkNonNullOfType(columnIndex, Type.array(Type.string()), columnName); + checkNonNullOfTypes( + columnIndex, + Arrays.asList(Type.array(Type.string()), Type.array(Type.pgNumeric())), + columnName, + "ARRAY, ARRAY"); return getStringListInternal(columnIndex); } @@ -429,6 +443,21 @@ private void checkNonNullOfType(int columnIndex, Type expectedType, Object colum checkNonNull(columnIndex, columnNameForError); } + private void checkNonNullOfTypes( + int columnIndex, + List expectedTypes, + Object columnNameForError, + String expectedTypeNames) { + Type actualType = getColumnType(columnIndex); + checkState( + expectedTypes.contains(actualType), + "Column %s is not of correct type: expected one of [%s] but was %s", + columnNameForError, + expectedTypeNames, + actualType); + checkNonNull(columnIndex, columnNameForError); + } + private void checkNonNullArrayOfStruct(int columnIndex, Object columnNameForError) { Type actualType = getColumnType(columnIndex); checkState( diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Database.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Database.java index 30d5017272c..eb3afdca705 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Database.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Database.java @@ -188,6 +188,7 @@ static Database fromProto( .setEarliestVersionTime(Timestamp.fromProto(proto.getEarliestVersionTime())) .setEncryptionConfig(CustomerManagedEncryption.fromProtoOrNull(proto.getEncryptionConfig())) .setDefaultLeader(proto.getDefaultLeader()) + .setDialect(Dialect.fromProto(proto.getDatabaseDialect())) .setProto(proto) .build(); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java index 4d79ed517da..52df8701556 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClientImpl.java @@ -23,7 +23,6 @@ import com.google.cloud.Policy; import com.google.cloud.Policy.DefaultMarshaller; import com.google.cloud.Timestamp; -import com.google.cloud.spanner.DatabaseInfo.State; import com.google.cloud.spanner.Options.ListOption; import com.google.cloud.spanner.SpannerImpl.PageFetcher; import com.google.cloud.spanner.spi.v1.SpannerRpc; @@ -281,14 +280,18 @@ public Backup fromProto(com.google.spanner.admin.database.v1.Backup proto) { public OperationFuture createDatabase( String instanceId, String databaseId, Iterable statements) throws SpannerException { return createDatabase( - new Database(DatabaseId.of(projectId, instanceId, databaseId), State.UNSPECIFIED, this), + newDatabaseBuilder(DatabaseId.of(projectId, instanceId, databaseId)) + .setDialect(Dialect.GOOGLE_STANDARD_SQL) + .build(), statements); } @Override public OperationFuture createDatabase( Database database, Iterable statements) throws SpannerException { - String createStatement = "CREATE DATABASE `" + database.getId().getDatabase() + "`"; + final Dialect dialect = Preconditions.checkNotNull(database.getDialect()); + final String createStatement = + dialect.createDatabaseStatementFor(database.getId().getDatabase()); OperationFuture rawOperationFuture = rpc.createDatabase( diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java index b58769bcb54..565517e3419 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java @@ -54,6 +54,10 @@ public Builder setDefaultLeader(String defaultLeader) { throw new UnsupportedOperationException("Unimplemented"); } + public Builder setDialect(Dialect dialect) { + throw new UnsupportedOperationException("Unimplemented"); + } + abstract Builder setProto(com.google.spanner.admin.database.v1.Database proto); /** Builds the database from this builder. */ @@ -69,6 +73,7 @@ abstract static class BuilderImpl extends Builder { private Timestamp earliestVersionTime; private CustomerManagedEncryption encryptionConfig; private String defaultLeader; + private Dialect dialect = Dialect.GOOGLE_STANDARD_SQL; private com.google.spanner.admin.database.v1.Database proto; BuilderImpl(DatabaseId id) { @@ -84,6 +89,7 @@ abstract static class BuilderImpl extends Builder { this.earliestVersionTime = other.earliestVersionTime; this.encryptionConfig = other.encryptionConfig; this.defaultLeader = other.defaultLeader; + this.dialect = other.dialect; this.proto = other.proto; } @@ -129,6 +135,12 @@ public Builder setDefaultLeader(String defaultLeader) { return this; } + @Override + public Builder setDialect(Dialect dialect) { + this.dialect = dialect; + return this; + } + @Override Builder setProto(@Nullable com.google.spanner.admin.database.v1.Database proto) { this.proto = proto; @@ -156,6 +168,7 @@ public enum State { private final Timestamp earliestVersionTime; private final CustomerManagedEncryption encryptionConfig; private final String defaultLeader; + private final Dialect dialect; private final com.google.spanner.admin.database.v1.Database proto; public DatabaseInfo(DatabaseId id, State state) { @@ -167,6 +180,7 @@ public DatabaseInfo(DatabaseId id, State state) { this.earliestVersionTime = null; this.encryptionConfig = null; this.defaultLeader = null; + this.dialect = null; this.proto = null; } @@ -179,6 +193,7 @@ public DatabaseInfo(DatabaseId id, State state) { this.earliestVersionTime = builder.earliestVersionTime; this.encryptionConfig = builder.encryptionConfig; this.defaultLeader = builder.defaultLeader; + this.dialect = builder.dialect; this.proto = builder.proto; } @@ -239,6 +254,14 @@ public Timestamp getEarliestVersionTime() { return defaultLeader; } + /** + * The dialect that is used by the database. It can be one of the values as specified in {@link + * Dialect#values()}. + */ + public @Nullable Dialect getDialect() { + return dialect; + } + /** Returns the raw proto instance that was used to construct this {@link Database}. */ public @Nullable com.google.spanner.admin.database.v1.Database getProto() { return proto; @@ -260,7 +283,8 @@ public boolean equals(Object o) { && Objects.equals(versionRetentionPeriod, that.versionRetentionPeriod) && Objects.equals(earliestVersionTime, that.earliestVersionTime) && Objects.equals(encryptionConfig, that.encryptionConfig) - && Objects.equals(defaultLeader, that.defaultLeader); + && Objects.equals(defaultLeader, that.defaultLeader) + && Objects.equals(dialect, that.dialect); } @Override @@ -273,13 +297,14 @@ public int hashCode() { versionRetentionPeriod, earliestVersionTime, encryptionConfig, - defaultLeader); + defaultLeader, + dialect); } @Override public String toString() { return String.format( - "Database[%s, %s, %s, %s, %s, %s, %s, %s]", + "Database[%s, %s, %s, %s, %s, %s, %s, %s, %s]", id.getName(), state, createTime, @@ -287,6 +312,7 @@ public String toString() { versionRetentionPeriod, earliestVersionTime, encryptionConfig, - defaultLeader); + defaultLeader, + dialect); } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Dialect.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Dialect.java new file mode 100644 index 00000000000..ba7186d8047 --- /dev/null +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Dialect.java @@ -0,0 +1,83 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner; + +import com.google.common.collect.ImmutableMap; +import com.google.spanner.admin.database.v1.DatabaseDialect; +import java.util.Arrays; +import java.util.Map; +import java.util.stream.Collectors; + +public enum Dialect { + GOOGLE_STANDARD_SQL { + @Override + public String createDatabaseStatementFor(String databaseName) { + return "CREATE DATABASE `" + databaseName + "`"; + } + + @Override + public DatabaseDialect toProto() { + return DatabaseDialect.GOOGLE_STANDARD_SQL; + } + }, + POSTGRESQL { + @Override + public String createDatabaseStatementFor(String databaseName) { + return "CREATE DATABASE \"" + databaseName + "\""; + } + + @Override + public DatabaseDialect toProto() { + return DatabaseDialect.POSTGRESQL; + } + }; + + private static final Map protoToDialect = + ImmutableMap.of( + DatabaseDialect.DATABASE_DIALECT_UNSPECIFIED, Dialect.GOOGLE_STANDARD_SQL, + DatabaseDialect.GOOGLE_STANDARD_SQL, Dialect.GOOGLE_STANDARD_SQL, + DatabaseDialect.POSTGRESQL, Dialect.POSTGRESQL); + + public abstract String createDatabaseStatementFor(String databaseName); + + public abstract DatabaseDialect toProto(); + + public static Dialect fromProto(DatabaseDialect databaseDialect) { + final Dialect dialect = protoToDialect.get(databaseDialect); + if (dialect == null) { + throw new IllegalArgumentException( + String.format( + "Invalid dialect: %s. Dialect must be one of [%s]", + databaseDialect, + protoToDialect.keySet().stream() + .map(DatabaseDialect::name) + .collect(Collectors.joining(", ")))); + } + return dialect; + } + + public static Dialect fromName(String name) { + try { + return Dialect.valueOf(name); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + String.format( + "Invalid dialect: %s. Dialect must be one of %s", + name, Arrays.toString(Dialect.values()))); + } + } +} diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Mutation.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Mutation.java index dd043653566..73995a20df8 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Mutation.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Mutation.java @@ -385,7 +385,9 @@ private boolean areValuesEqual(List values, List otherValues) { } private boolean isNaN(Value value) { - return !value.isNull() && value.getType() == Type.float64() && Double.isNaN(value.getFloat64()); + return !value.isNull() + && value.getType().equals(Type.float64()) + && Double.isNaN(value.getFloat64()); } static void toProto(Iterable mutations, List out) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java index 5d1a51390d7..14f07314e8f 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java @@ -125,6 +125,7 @@ public class SpannerOptions extends ServiceOptions { private final CallCredentialsProvider callCredentialsProvider; private final CloseableExecutorProvider asyncExecutorProvider; private final String compressorName; + private final Dialect dialect; /** * Interface that can be used to provide {@link CallCredentials} instead of {@link Credentials} to @@ -592,6 +593,7 @@ private SpannerOptions(Builder builder) { callCredentialsProvider = builder.callCredentialsProvider; asyncExecutorProvider = builder.asyncExecutorProvider; compressorName = builder.compressorName; + dialect = builder.dialect; } /** @@ -691,6 +693,7 @@ public static class Builder private CloseableExecutorProvider asyncExecutorProvider; private String compressorName; private String emulatorHost = System.getenv("SPANNER_EMULATOR_HOST"); + private Dialect dialect = Dialect.GOOGLE_STANDARD_SQL; private Builder() { // Manually set retry and polling settings that work. @@ -745,6 +748,7 @@ private Builder() { this.channelProvider = options.channelProvider; this.channelConfigurator = options.channelConfigurator; this.interceptorProvider = options.interceptorProvider; + this.dialect = options.dialect; } @Override @@ -764,6 +768,20 @@ protected Set getAllowedClientLibTokens() { /** * Sets the {@code ChannelProvider}. {@link GapicSpannerRpc} would create a default one if none * is provided. + * + *

Setting a custom {@link TransportChannelProvider} also overrides any other settings that + * affect the default channel provider. These must be set manually on the custom {@link + * TransportChannelProvider} instead of on {@link SpannerOptions}. The settings of {@link + * SpannerOptions} that have no effect if you set a custom {@link TransportChannelProvider} are: + * + *

    + *
  1. {@link #setChannelConfigurator(ApiFunction)} + *
  2. {@link #setHost(String)} + *
  3. {@link #setNumChannels(int)} + *
  4. {@link #setInterceptorProvider(GrpcInterceptorProvider)} + *
  5. {@link #setDialect(Dialect)} + *
  6. {@link #setHeaderProvider(com.google.api.gax.rpc.HeaderProvider)} + *
*/ public Builder setChannelProvider(TransportChannelProvider channelProvider) { this.channelProvider = channelProvider; @@ -1121,6 +1139,17 @@ public Builder setEmulatorHost(String emulatorHost) { return this; } + /** + * Sets the {@link Dialect} to use with Cloud Spanner. The default is {@link + * Dialect#GOOGLE_STANDARD_SQL}. + */ + public Builder setDialect(Dialect dialect) { + Preconditions.checkNotNull(dialect); + this.dialect = dialect; + return this; + } + + @SuppressWarnings("rawtypes") @Override public SpannerOptions build() { // Set the host of emulator has been set. @@ -1247,6 +1276,10 @@ public String getCompressorName() { return compressorName; } + public Dialect getDialect() { + return dialect; + } + /** Returns the default query options to use for the specific database. */ public QueryOptions getDefaultQueryOptions(DatabaseId databaseId) { // Use the specific query options for the database if any have been specified. These have diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java index 9a437f2be31..c986767d3a0 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Struct.java @@ -349,6 +349,8 @@ private Object getAsObject(int columnIndex) { return getDoubleInternal(columnIndex); case NUMERIC: return getBigDecimalInternal(columnIndex); + case PG_NUMERIC: + return getStringInternal(columnIndex); case STRING: return getStringInternal(columnIndex); case JSON: @@ -371,6 +373,8 @@ private Object getAsObject(int columnIndex) { return getDoubleListInternal(columnIndex); case NUMERIC: return getBigDecimalListInternal(columnIndex); + case PG_NUMERIC: + return getStringListInternal(columnIndex); case STRING: return getStringListInternal(columnIndex); case JSON: diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java index 4a78eca4674..15305e0cdab 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java @@ -17,16 +17,20 @@ package com.google.cloud.spanner; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.spanner.v1.TypeAnnotationCode.TYPE_ANNOTATION_CODE_UNSPECIFIED; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.spanner.v1.TypeAnnotationCode; import com.google.spanner.v1.TypeCode; import java.io.Serializable; +import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.TreeMap; import javax.annotation.Nullable; @@ -45,6 +49,7 @@ public final class Type implements Serializable { private static final Type TYPE_INT64 = new Type(Code.INT64, null, null); private static final Type TYPE_FLOAT64 = new Type(Code.FLOAT64, null, null); private static final Type TYPE_NUMERIC = new Type(Code.NUMERIC, null, null); + private static final Type TYPE_PG_NUMERIC = new Type(Code.PG_NUMERIC, null, null); private static final Type TYPE_STRING = new Type(Code.STRING, null, null); private static final Type TYPE_JSON = new Type(Code.JSON, null, null); private static final Type TYPE_BYTES = new Type(Code.BYTES, null, null); @@ -54,6 +59,7 @@ public final class Type implements Serializable { private static final Type TYPE_ARRAY_INT64 = new Type(Code.ARRAY, TYPE_INT64, null); private static final Type TYPE_ARRAY_FLOAT64 = new Type(Code.ARRAY, TYPE_FLOAT64, null); private static final Type TYPE_ARRAY_NUMERIC = new Type(Code.ARRAY, TYPE_NUMERIC, null); + private static final Type TYPE_ARRAY_PG_NUMERIC = new Type(Code.ARRAY, TYPE_PG_NUMERIC, null); private static final Type TYPE_ARRAY_STRING = new Type(Code.ARRAY, TYPE_STRING, null); private static final Type TYPE_ARRAY_JSON = new Type(Code.ARRAY, TYPE_JSON, null); private static final Type TYPE_ARRAY_BYTES = new Type(Code.ARRAY, TYPE_BYTES, null); @@ -89,6 +95,14 @@ public static Type numeric() { return TYPE_NUMERIC; } + /** + * Returns the descriptor for the {@code NUMERIC} type with the {@code PG_NUMERIC} type + * annotation. + */ + public static Type pgNumeric() { + return Type.TYPE_PG_NUMERIC; + } + /** * Returns the descriptor for the {@code STRING} type: a variable-length Unicode character string. */ @@ -134,6 +148,8 @@ public static Type array(Type elementType) { return TYPE_ARRAY_FLOAT64; case NUMERIC: return TYPE_ARRAY_NUMERIC; + case PG_NUMERIC: + return TYPE_ARRAY_PG_NUMERIC; case STRING: return TYPE_ARRAY_STRING; case JSON: @@ -189,6 +205,7 @@ public enum Code { BOOL(TypeCode.BOOL), INT64(TypeCode.INT64), NUMERIC(TypeCode.NUMERIC), + PG_NUMERIC(TypeCode.NUMERIC, TypeAnnotationCode.PG_NUMERIC), FLOAT64(TypeCode.FLOAT64), STRING(TypeCode.STRING), JSON(TypeCode.JSON), @@ -198,31 +215,51 @@ public enum Code { ARRAY(TypeCode.ARRAY), STRUCT(TypeCode.STRUCT); - private static final Map protoToCode; + private static final Map, Code> protoToCode; static { - ImmutableMap.Builder builder = ImmutableMap.builder(); + ImmutableMap.Builder, Code> builder = + ImmutableMap.builder(); for (Code code : Code.values()) { - builder.put(code.protoCode(), code); + builder.put(new SimpleEntry<>(code.getTypeCode(), code.getTypeAnnotationCode()), code); } protoToCode = builder.build(); } - private final TypeCode protoCode; + private final TypeCode typeCode; + private final TypeAnnotationCode typeAnnotationCode; + + Code(TypeCode typeCode) { + this(typeCode, TYPE_ANNOTATION_CODE_UNSPECIFIED); + } + + Code(TypeCode typeCode, TypeAnnotationCode typeAnnotationCode) { + this.typeCode = typeCode; + this.typeAnnotationCode = typeAnnotationCode; + } - Code(TypeCode protoCode) { - this.protoCode = protoCode; + TypeCode getTypeCode() { + return typeCode; } - TypeCode protoCode() { - return protoCode; + TypeAnnotationCode getTypeAnnotationCode() { + return typeAnnotationCode; } - static Code fromProtoCode(TypeCode protoCode) { - Code code = protoToCode.get(protoCode); - checkArgument(code != null, "Invalid code: %s", protoCode); + static Code fromProto(TypeCode typeCode, TypeAnnotationCode typeAnnotationCode) { + Code code = protoToCode.get(new SimpleEntry<>(typeCode, typeAnnotationCode)); + checkArgument(code != null, "Invalid code: %s<%s>", typeCode, typeAnnotationCode); return code; } + + @Override + public String toString() { + if (typeAnnotationCode == TYPE_ANNOTATION_CODE_UNSPECIFIED) { + return typeCode.toString(); + } else { + return typeCode.toString() + "<" + typeAnnotationCode.toString() + ">"; + } + } } /** Describes an individual field in a {@code STRUCT type}. */ @@ -379,7 +416,8 @@ public int hashCode() { com.google.spanner.v1.Type toProto() { com.google.spanner.v1.Type.Builder proto = com.google.spanner.v1.Type.newBuilder(); - proto.setCode(code.protoCode()); + proto.setCode(code.getTypeCode()); + proto.setTypeAnnotation(code.getTypeAnnotationCode()); if (code == Code.ARRAY) { proto.setArrayElementType(arrayElementType.toProto()); } else if (code == Code.STRUCT) { @@ -392,7 +430,7 @@ com.google.spanner.v1.Type toProto() { } static Type fromProto(com.google.spanner.v1.Type proto) { - Code type = Code.fromProtoCode(proto.getCode()); + Code type = Code.fromProto(proto.getCode(), proto.getTypeAnnotation()); switch (type) { case BOOL: return bool(); @@ -402,6 +440,8 @@ static Type fromProto(com.google.spanner.v1.Type proto) { return float64(); case NUMERIC: return numeric(); + case PG_NUMERIC: + return pgNumeric(); case STRING: return string(); case JSON: diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java index 090c636b59d..38b4361d755 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Value.java @@ -35,6 +35,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -72,6 +73,9 @@ public abstract class Value implements Serializable { */ public static final Timestamp COMMIT_TIMESTAMP = Timestamp.ofTimeMicroseconds(0L); + /** Constant to specify a PG Numeric NaN value. */ + public static final String NAN = "NaN"; + private static final int MAX_DEBUG_STRING_LENGTH = 36; private static final String ELLIPSIS = "..."; private static final String NULL_STRING = "NULL"; @@ -157,6 +161,21 @@ public static Value numeric(@Nullable BigDecimal v) { return new NumericImpl(v == null, v); } + /** + * Returns a {@code PG NUMERIC} value. This value has flexible precision and scale which is + * specified in the Database DDL. This value also supports {@code NaNs}, which can be specified + * with {@code Value.pgNumeric(Value.NAN)} or simply as {@code Value.pgNumeric("NaN")}. + * + *

Note that this flavour of numeric is different than Spanner numerics ({@link + * Value#numeric(BigDecimal)}). It should be used only for handling numerics in the PostgreSQL + * dialect. + * + * @param v the value, which may be null + */ + public static Value pgNumeric(@Nullable String v) { + return new PgNumericImpl(v == null, v); + } + /** * Returns a {@code STRING} value. * @@ -338,6 +357,17 @@ public static Value numericArray(@Nullable Iterable v) { return new NumericArrayImpl(v == null, v == null ? null : immutableCopyOf(v)); } + /** + * Returns an {@code ARRAY} value. + * + * @param v the source of element values. This may be {@code null} to produce a value for which + * {@code isNull()} is {@code true}. Individual elements may also be {@code null}. Individual + * elements may be {@code "NaN"} or {@link Value#NAN}. + */ + public static Value pgNumericArray(@Nullable Iterable v) { + return new PgNumericArrayImpl(v == null, v == null ? null : immutableCopyOf(v)); + } + /** * Returns an {@code ARRAY} value. * @@ -1232,6 +1262,65 @@ void valueToString(StringBuilder b) { } } + private static class PgNumericImpl extends AbstractObjectValue { + private BigDecimal valueAsBigDecimal; + private NumberFormatException bigDecimalConversionError; + private Double valueAsDouble; + private NumberFormatException doubleConversionError; + + private PgNumericImpl(boolean isNull, String value) { + super(isNull, Type.pgNumeric(), value); + } + + @Override + public String getString() { + checkType(Type.pgNumeric()); + checkNotNull(); + return value; + } + + @Override + public BigDecimal getNumeric() { + checkType(Type.pgNumeric()); + checkNotNull(); + if (bigDecimalConversionError != null) { + throw bigDecimalConversionError; + } + if (valueAsBigDecimal == null) { + try { + valueAsBigDecimal = new BigDecimal(value); + } catch (NumberFormatException e) { + bigDecimalConversionError = e; + throw e; + } + } + return valueAsBigDecimal; + } + + @Override + public double getFloat64() { + checkType(Type.pgNumeric()); + checkNotNull(); + if (doubleConversionError != null) { + throw doubleConversionError; + } + if (valueAsDouble == null) { + try { + valueAsDouble = Double.parseDouble(value); + } catch (NumberFormatException e) { + doubleConversionError = e; + throw e; + } + } + return valueAsDouble; + } + + @Override + void valueToString(StringBuilder b) { + b.append(value); + } + } + private abstract static class PrimitiveArrayImpl extends AbstractValue { private final BitSet nulls; @@ -1580,6 +1669,72 @@ void appendElement(StringBuilder b, BigDecimal element) { } } + private static class PgNumericArrayImpl extends AbstractArrayValue { + + private List valuesAsBigDecimal; + private NumberFormatException bigDecimalConversionError; + private List valuesAsDouble; + private NumberFormatException doubleConversionError; + + private PgNumericArrayImpl(boolean isNull, @Nullable List values) { + super(isNull, Type.pgNumeric(), values); + } + + @Override + public List getStringArray() { + checkType(getType()); + checkNotNull(); + return value; + } + + @Override + public List getNumericArray() { + checkType(getType()); + checkNotNull(); + if (bigDecimalConversionError != null) { + throw bigDecimalConversionError; + } + if (valuesAsBigDecimal == null) { + try { + valuesAsBigDecimal = + value.stream() + .map(v -> v == null ? null : new BigDecimal(v)) + .collect(Collectors.toList()); + } catch (NumberFormatException e) { + bigDecimalConversionError = e; + throw e; + } + } + return valuesAsBigDecimal; + } + + @Override + public List getFloat64Array() { + checkType(getType()); + checkNotNull(); + if (doubleConversionError != null) { + throw doubleConversionError; + } + if (valuesAsDouble == null) { + try { + valuesAsDouble = + value.stream() + .map(v -> v == null ? null : Double.valueOf(v)) + .collect(Collectors.toList()); + } catch (NumberFormatException e) { + doubleConversionError = e; + throw e; + } + } + return valuesAsDouble; + } + + @Override + void appendElement(StringBuilder b, String element) { + b.append(element); + } + } + private static class StructImpl extends AbstractObjectValue { // Constructor for non-NULL struct values. @@ -1631,6 +1786,8 @@ private Value getValue(int fieldIndex) { return Value.float64(value.getDouble(fieldIndex)); case NUMERIC: return Value.numeric(value.getBigDecimal(fieldIndex)); + case PG_NUMERIC: + return Value.pgNumeric(value.getString(fieldIndex)); case DATE: return Value.date(value.getDate(fieldIndex)); case TIMESTAMP: @@ -1655,6 +1812,8 @@ private Value getValue(int fieldIndex) { return Value.float64Array(value.getDoubleList(fieldIndex)); case NUMERIC: return Value.numericArray(value.getBigDecimalList(fieldIndex)); + case PG_NUMERIC: + return Value.pgNumericArray(value.getStringList(fieldIndex)); case DATE: return Value.dateArray(value.getDateList(fieldIndex)); case TIMESTAMP: diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ValueBinder.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ValueBinder.java index 07dd246e7b4..cdca5d84a25 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ValueBinder.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ValueBinder.java @@ -173,6 +173,11 @@ public R toNumericArray(@Nullable Iterable values) { return handle(Value.numericArray(values)); } + /** Binds to {@code Value.pgNumericArray(values)} */ + public R toPgNumericArray(@Nullable Iterable values) { + return handle(Value.pgNumericArray(values)); + } + /** Binds to {@code Value.stringArray(values)} */ public R toStringArray(@Nullable Iterable values) { return handle(Value.stringArray(values)); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractBaseUnitOfWork.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractBaseUnitOfWork.java index a21c4880ecb..e9117287853 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractBaseUnitOfWork.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractBaseUnitOfWork.java @@ -27,8 +27,8 @@ import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.SpannerOptions; import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.StatementExecutor.StatementTimeout; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.MoreExecutors; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractMultiUseTransaction.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractMultiUseTransaction.java index ac3c7cb86a1..88dabb7763b 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractMultiUseTransaction.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractMultiUseTransaction.java @@ -23,7 +23,7 @@ import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.common.base.Preconditions; import com.google.spanner.v1.SpannerGrpc; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementParser.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java similarity index 57% rename from google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementParser.java rename to google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java index f3822177f04..62cee4e26e1 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementParser.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java @@ -17,18 +17,23 @@ package com.google.cloud.spanner.connection; import com.google.api.core.InternalApi; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; +import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.connection.ClientSideStatementImpl.CompileException; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; import com.google.spanner.v1.ExecuteSqlRequest.QueryOptions; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.Callable; /** * Internal class for the Spanner Connection API. @@ -37,12 +42,92 @@ * the type of statement, allowing the connection API to know which method on Spanner should be * called. The parser does not validate the validity of statements, except for {@link * ClientSideStatement}s. This means that an invalid DML statement could be accepted by the {@link - * StatementParser} and sent to Spanner, and Spanner will then reject it with some error message. + * AbstractStatementParser} and sent to Spanner, and Spanner will then reject it with some error + * message. */ @InternalApi -public class StatementParser { - /** Singleton instance of {@link StatementParser}. */ - public static final StatementParser INSTANCE = new StatementParser(); +public abstract class AbstractStatementParser { + private static final Object lock = new Object(); + private static final Map INSTANCES = new HashMap<>(); + private static final ImmutableMap> + KNOWN_PARSER_CLASSES = + ImmutableMap.of( + Dialect.GOOGLE_STANDARD_SQL, + SpannerStatementParser.class, + Dialect.POSTGRESQL, + PostgreSQLStatementParser.class); + private static final String GSQL_STATEMENT = "/*GSQL*/"; + + /* Checks if the SQL statement starts with /*GSQL*/ + private boolean isGoogleSql(String sql) { + return sql.startsWith(GSQL_STATEMENT); + } + + /** Get an instance of {@link AbstractStatementParser} for the specified dialect. */ + public static AbstractStatementParser getInstance(Dialect dialect) { + synchronized (lock) { + if (!INSTANCES.containsKey(dialect)) { + try { + Class clazz = KNOWN_PARSER_CLASSES.get(dialect); + if (clazz == null) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INTERNAL, "There is no known statement parser for dialect " + dialect); + } + INSTANCES.put(dialect, clazz.newInstance()); + } catch (InstantiationException | IllegalAccessException e) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INTERNAL, + "Could not instantiate statement parser for dialect " + dialect.name(), + e); + } + } + return INSTANCES.get(dialect); + } + } + + /** + * The following fixed pre-parsed statements are used internally by the Connection API. These do + * not need to be parsed using a specific dialect, as they are equal for all dialects, and + * pre-parsing them avoids the need to repeatedly parse statements that are used internally. + */ + + /** Begins a transaction. */ + static final ParsedStatement BEGIN_STATEMENT = + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL).parse(Statement.of("BEGIN")); + + /** + * Create a COMMIT statement to use with the {@link #commit()} method to allow it to be cancelled, + * time out or retried. + * + *

{@link ReadWriteTransaction} uses the generic methods {@link #executeAsync(ParsedStatement, + * Callable)} and {@link #runWithRetry(Callable)} to allow statements to be cancelled, to timeout + * and to be retried. These methods require a {@link ParsedStatement} as input. When the {@link + * #commit()} method is called directly, we do not have a {@link ParsedStatement}, and the method + * uses this statement instead in order to use the same logic as the other statements. + */ + static final ParsedStatement COMMIT_STATEMENT = + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("COMMIT")); + + /** The {@link Statement} and {@link Callable} for rollbacks */ + static final ParsedStatement ROLLBACK_STATEMENT = + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("ROLLBACK")); + + /** + * Create a RUN BATCH statement to use with the {@link #executeBatchUpdate(Iterable)} method to + * allow it to be cancelled, time out or retried. + * + *

{@link ReadWriteTransaction} uses the generic methods {@link #executeAsync(ParsedStatement, + * Callable)} and {@link #runWithRetry(Callable)} to allow statements to be cancelled, to timeout + * and to be retried. These methods require a {@link ParsedStatement} as input. When the {@link + * #executeBatchUpdate(Iterable)} method is called, we do not have one {@link ParsedStatement}, + * and the method uses this statement instead in order to use the same logic as the other + * statements. + */ + static final ParsedStatement RUN_BATCH_STATEMENT = + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("RUN BATCH")); /** The type of statement that has been recognized by the parser. */ enum StatementType { @@ -213,13 +298,14 @@ ClientSideStatement getClientSideStatement() { } } - private static final Set ddlStatements = ImmutableSet.of("CREATE", "DROP", "ALTER"); - private static final Set selectStatements = ImmutableSet.of("SELECT", "WITH"); - private static final Set dmlStatements = ImmutableSet.of("INSERT", "UPDATE", "DELETE"); + static final Set ddlStatements = ImmutableSet.of("CREATE", "DROP", "ALTER"); + static final Set selectStatements = ImmutableSet.of("SELECT", "WITH", "SHOW"); + static final Set dmlStatements = ImmutableSet.of("INSERT", "UPDATE", "DELETE"); + private final Dialect dialect; private final Set statements; - /** Private constructor for singleton instance. */ - private StatementParser() { + AbstractStatementParser(Dialect dialect) { + this.dialect = dialect; try { statements = Collections.unmodifiableSet(ClientSideStatements.INSTANCE.getCompiledStatements()); @@ -299,6 +385,8 @@ public boolean isDdlStatement(String sql) { @InternalApi public boolean isQuery(String sql) { // Skip any query hints at the beginning of the query. + // We only do this if we actually know that it starts with a hint to prevent unnecessary + // re-assigning the exact same sql string. if (sql.startsWith("@")) { sql = removeStatementHint(sql); } @@ -323,12 +411,23 @@ public boolean isUpdateStatement(String sql) { return statementStartsWith(sql, dmlStatements); } + protected abstract boolean supportsExplain(); + private boolean statementStartsWith(String sql, Iterable checkStatements) { Preconditions.checkNotNull(sql); - String[] tokens = sql.split("\\s+", 2); - if (tokens.length > 0) { + String[] tokens; + if (isGoogleSql(sql)) { + tokens = sql.substring(GSQL_STATEMENT.length()).split("\\s+", 2); + } else { + tokens = sql.split("\\s+", 2); + } + int checkIndex = 0; + if (supportsExplain() && tokens[0].equalsIgnoreCase("EXPLAIN")) { + checkIndex = 1; + } + if (tokens.length > checkIndex) { for (String check : checkStatements) { - if (tokens[0].equalsIgnoreCase(check)) { + if (tokens[checkIndex].equalsIgnoreCase(check)) { return true; } } @@ -336,149 +435,95 @@ private boolean statementStartsWith(String sql, Iterable checkStatements return false; } + static final char SINGLE_QUOTE = '\''; + static final char DOUBLE_QUOTE = '"'; + static final char BACKTICK_QUOTE = '`'; + static final char HYPHEN = '-'; + static final char DASH = '#'; + static final char SLASH = '/'; + static final char ASTERIKS = '*'; + static final char DOLLAR = '$'; + /** - * Removes comments from and trims the given sql statement. Spanner supports three types of - * comments: - * - *

    - *
  • Single line comments starting with '--' - *
  • Single line comments starting with '#' - *
  • Multi line comments between '/*' and '*/' - *
- * - * Reference: https://cloud.google.com/spanner/docs/lexical#comments + * Removes comments from and trims the given sql statement using the dialect of this parser. * * @param sql The sql statement to remove comments from and to trim. * @return the sql statement without the comments and leading and trailing spaces. */ @InternalApi - public static String removeCommentsAndTrim(String sql) { - Preconditions.checkNotNull(sql); - final char SINGLE_QUOTE = '\''; - final char DOUBLE_QUOTE = '"'; - final char BACKTICK_QUOTE = '`'; - final char HYPHEN = '-'; - final char DASH = '#'; - final char SLASH = '/'; - final char ASTERISK = '*'; - boolean isInQuoted = false; - boolean isInSingleLineComment = false; - boolean isInMultiLineComment = false; - char startQuote = 0; - boolean lastCharWasEscapeChar = false; - boolean isTripleQuoted = false; - StringBuilder res = new StringBuilder(sql.length()); - int index = 0; - while (index < sql.length()) { - char c = sql.charAt(index); - if (isInQuoted) { - if ((c == '\n' || c == '\r') && !isTripleQuoted) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); - } else if (c == startQuote) { - if (lastCharWasEscapeChar) { - lastCharWasEscapeChar = false; - } else if (isTripleQuoted) { - if (sql.length() > index + 2 - && sql.charAt(index + 1) == startQuote - && sql.charAt(index + 2) == startQuote) { - isInQuoted = false; - startQuote = 0; - isTripleQuoted = false; - res.append(c).append(c); - index += 2; - } - } else { - isInQuoted = false; - startQuote = 0; - } - } else if (c == '\\') { - lastCharWasEscapeChar = true; - } else { - lastCharWasEscapeChar = false; - } - res.append(c); - } else { - // We are not in a quoted string. - if (isInSingleLineComment) { - if (c == '\n') { - isInSingleLineComment = false; - // Include the line feed in the result. - res.append(c); - } - } else if (isInMultiLineComment) { - if (sql.length() > index + 1 && c == ASTERISK && sql.charAt(index + 1) == SLASH) { - isInMultiLineComment = false; - index++; - } + abstract String removeCommentsAndTrimInternal(String sql); + + @InternalApi + public String removeCommentsAndTrim(String sql) { + switch (dialect) { + case POSTGRESQL: + if (isGoogleSql(sql.trim())) { + return GSQL_STATEMENT + + INSTANCES.get(Dialect.GOOGLE_STANDARD_SQL).removeCommentsAndTrimInternal(sql); } else { - if (c == DASH - || (sql.length() > index + 1 && c == HYPHEN && sql.charAt(index + 1) == HYPHEN)) { - // This is a single line comment. - isInSingleLineComment = true; - } else if (sql.length() > index + 1 && c == SLASH && sql.charAt(index + 1) == ASTERISK) { - isInMultiLineComment = true; - index++; - } else { - if (c == SINGLE_QUOTE || c == DOUBLE_QUOTE || c == BACKTICK_QUOTE) { - isInQuoted = true; - startQuote = c; - // Check whether it is a triple-quote. - if (sql.length() > index + 2 - && sql.charAt(index + 1) == startQuote - && sql.charAt(index + 2) == startQuote) { - isTripleQuoted = true; - res.append(c).append(c); - index += 2; - } - } - res.append(c); - } + return removeCommentsAndTrimInternal(sql); } - } - index++; - } - if (isInQuoted) { - throw SpannerExceptionFactory.newSpannerException( - ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); + case GOOGLE_STANDARD_SQL: + return removeCommentsAndTrimInternal(sql); + default: + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INTERNAL, "Unknown dialect: " + dialect); } - if (res.length() > 0 && res.charAt(res.length() - 1) == ';') { - res.deleteCharAt(res.length() - 1); - } - return res.toString().trim(); } /** Removes any statement hints at the beginning of the statement. */ - static String removeStatementHint(String sql) { - // Valid statement hints at the beginning of a query statement can only contain a fixed set of - // possible values. Although it is possible to add a @{FORCE_INDEX=...} as a statement hint, the - // only allowed value is _BASE_TABLE. This means that we can safely assume that the statement - // hint will not contain any special characters, for example a closing curly brace or one of the - // keywords SELECT, UPDATE, DELETE, WITH, and that we can keep the check simple by just - // searching for the first occurrence of a keyword that should be preceded by a closing curly - // brace at the end of the statement hint. - int startStatementHintIndex = sql.indexOf('{'); - // Statement hints are allowed for both queries and DML statements. - int startQueryIndex = -1; - String upperCaseSql = sql.toUpperCase(); - Set selectAndDmlStatements = - Sets.union(selectStatements, dmlStatements).immutableCopy(); - for (String keyword : selectAndDmlStatements) { - startQueryIndex = upperCaseSql.indexOf(keyword); - if (startQueryIndex > -1) { - break; - } + abstract String removeStatementHint(String sql); + + /** Parameter information with positional parameters translated to named parameters. */ + @InternalApi + public static class ParametersInfo { + public final int numberOfParameters; + public final String sqlWithNamedParameters; + + ParametersInfo(int numberOfParameters, String sqlWithNamedParameters) { + this.numberOfParameters = numberOfParameters; + this.sqlWithNamedParameters = sqlWithNamedParameters; + } + } + + /** + * Converts all positional parameters (?) in the given sql string into named parameters. The + * parameters are named @p1, @p2, etc. This method is used when converting a JDBC statement that + * uses positional parameters to a Cloud Spanner {@link Statement} instance that requires named + * parameters. The input SQL string may not contain any comments. There is an exception case if + * the statement starts with a GSQL comment which forces it to be interpreted as a GoogleSql + * statement. + * + * @param sql The sql string without comments that should be converted + * @return A {@link ParametersInfo} object containing a string with named parameters instead of + * positional parameters and the number of parameters. + * @throws SpannerException If the input sql string contains an unclosed string/byte literal. + */ + @InternalApi + abstract ParametersInfo convertPositionalParametersToNamedParametersInternal( + char paramChar, String sql); + + @InternalApi + public ParametersInfo convertPositionalParametersToNamedParameters(char paramChar, String sql) { + if (dialect == Dialect.POSTGRESQL && isGoogleSql(sql.trim())) { + return INSTANCES + .get(Dialect.GOOGLE_STANDARD_SQL) + .convertPositionalParametersToNamedParametersInternal(paramChar, sql); + } else { + return INSTANCES + .get(dialect) + .convertPositionalParametersToNamedParametersInternal(paramChar, sql); } - if (startQueryIndex > -1) { - int endStatementHintIndex = sql.substring(0, startQueryIndex).lastIndexOf('}'); - if (startStatementHintIndex == -1 || startStatementHintIndex > endStatementHintIndex) { - // Looks like an invalid statement hint. Just ignore at this point and let the caller handle - // the invalid query. - return sql; + } + + /** Convenience method that is used to estimate the number of parameters in a SQL statement. */ + static int countOccurrencesOf(char c, String string) { + int res = 0; + for (int i = 0; i < string.length(); i++) { + if (string.charAt(i) == c) { + res++; } - return removeCommentsAndTrim(sql.substring(endStatementHintIndex + 1)); } - // Seems invalid, just return the original statement. - return sql; + return res; } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java index ba8f5950ae3..2c01396083e 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ChecksumResultSet.java @@ -26,8 +26,8 @@ import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.Type.Code; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.ReadWriteTransaction.RetriableStatement; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.hash.Funnel; @@ -236,6 +236,9 @@ public void funnel(Struct row, PrimitiveSink into) { case NUMERIC: funnelValue(type, row.getBigDecimal(i), into); break; + case PG_NUMERIC: + funnelValue(type, row.getString(i), into); + break; case INT64: funnelValue(type, row.getLong(i), into); break; @@ -291,6 +294,12 @@ private void funnelArray( funnelValue(Code.NUMERIC, value, into); } break; + case PG_NUMERIC: + into.putInt(row.getStringList(columnIndex).size()); + for (String value : row.getStringList(columnIndex)) { + funnelValue(Code.STRING, value, into); + } + break; case INT64: into.putInt(row.getLongList(columnIndex).size()); for (Long value : row.getLongList(columnIndex)) { @@ -358,6 +367,7 @@ private void funnelValue(Code type, T value, PrimitiveSink into) { case INT64: into.putLong((Long) value); break; + case PG_NUMERIC: case STRING: case JSON: String stringValue = (String) value; 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 f7d8e18e911..9c74e5b9ca1 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 @@ -23,6 +23,7 @@ import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.AsyncResultSet; import com.google.cloud.spanner.CommitResponse; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.Options.QueryOption; @@ -1098,6 +1099,11 @@ default RpcPriority getRPCPriority() { */ void bufferedWrite(Iterable mutations); + /** The {@link Dialect} that is used by this {@link Connection}. */ + default Dialect getDialect() { + throw new UnsupportedOperationException("Not implemented"); + } + /** * This query option is used internally to indicate that a query is executed by the library itself * to fetch metadata. These queries are specifically allowed to be executed even when a DDL batch 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 df8caa0ff85..9cea3810a98 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 @@ -24,6 +24,7 @@ import com.google.cloud.spanner.AsyncResultSet; import com.google.cloud.spanner.CommitResponse; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.Options; @@ -39,9 +40,9 @@ import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.TimestampBound.Mode; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.cloud.spanner.connection.StatementExecutor.StatementTimeout; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; -import com.google.cloud.spanner.connection.StatementParser.StatementType; import com.google.cloud.spanner.connection.UnitOfWork.UnitOfWorkState; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; @@ -82,7 +83,7 @@ private LeakedConnectionException() { private volatile LeakedConnectionException leakedException = new LeakedConnectionException(); private final SpannerPool spannerPool; - private final StatementParser parser = StatementParser.INSTANCE; + private final AbstractStatementParser parser; /** * The {@link ConnectionStatementExecutor} is responsible for translating parsed {@link * ClientSideStatement}s into actual method calls on this {@link ConnectionImpl}. I.e. the {@link @@ -220,6 +221,7 @@ static UnitOfWorkType of(TransactionMode transactionMode) { this.statementExecutor = new StatementExecutor(options.getStatementExecutionInterceptors()); this.spannerPool = SpannerPool.INSTANCE; this.options = options; + this.parser = AbstractStatementParser.getInstance(options.getDialect()); this.spanner = spannerPool.getSpanner(options, this); if (options.isAutoConfigEmulator()) { EmulatorUtil.maybeCreateInstanceAndDatabase(spanner, options.getDatabaseId()); @@ -249,6 +251,7 @@ static UnitOfWorkType of(TransactionMode transactionMode) { this.statementExecutor = new StatementExecutor(Collections.emptyList()); this.spannerPool = spannerPool; this.options = options; + this.parser = AbstractStatementParser.getInstance(options.getDialect()); this.spanner = spannerPool.getSpanner(options, this); this.ddlClient = ddlClient; this.dbClient = dbClient; @@ -319,6 +322,11 @@ LeakedConnectionException getLeakedException() { return leakedException; } + @Override + public Dialect getDialect() { + return options.getDialect(); + } + @Override public boolean isClosed() { return closed; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java index 47c2bad9789..eb6a430f6d0 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java @@ -17,6 +17,7 @@ package com.google.cloud.spanner.connection; import com.google.api.core.InternalApi; +import com.google.api.gax.rpc.TransportChannelProvider; import com.google.auth.Credentials; import com.google.auth.oauth2.AccessToken; import com.google.auth.oauth2.GoogleCredentials; @@ -24,6 +25,7 @@ import com.google.cloud.NoCredentials; import com.google.cloud.ServiceOptions; import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.Options.RpcPriority; import com.google.cloud.spanner.SessionPoolOptions; @@ -35,6 +37,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Sets; import com.google.spanner.v1.ExecuteSqlRequest.QueryOptions; +import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -156,12 +159,14 @@ public String[] getValidValues() { private static final String DEFAULT_MIN_SESSIONS = null; private static final String DEFAULT_MAX_SESSIONS = null; private static final String DEFAULT_NUM_CHANNELS = null; + private static final String DEFAULT_CHANNEL_PROVIDER = null; private static final String DEFAULT_USER_AGENT = null; private static final String DEFAULT_OPTIMIZER_VERSION = ""; private static final String DEFAULT_OPTIMIZER_STATISTICS_PACKAGE = ""; private static final RpcPriority DEFAULT_RPC_PRIORITY = null; private static final boolean DEFAULT_RETURN_COMMIT_STATS = false; private static final boolean DEFAULT_LENIENT = false; + private static final String DEFAULT_DIALECT = Dialect.GOOGLE_STANDARD_SQL.name(); private static final String PLAIN_TEXT_PROTOCOL = "http:"; private static final String HOST_PROTOCOL = "https:"; @@ -189,6 +194,8 @@ public String[] getValidValues() { public static final String MAX_SESSIONS_PROPERTY_NAME = "maxSessions"; /** Name of the 'numChannels' connection property. */ public static final String NUM_CHANNELS_PROPERTY_NAME = "numChannels"; + /** Name of the 'channelProvider' connection property. */ + public static final String CHANNEL_PROVIDER_PROPERTY_NAME = "channelProvider"; /** Custom user agent string is only for other Google libraries. */ private static final String USER_AGENT_PROPERTY_NAME = "userAgent"; /** Query optimizer version to use for a connection. */ @@ -200,6 +207,8 @@ public String[] getValidValues() { public static final String LENIENT_PROPERTY_NAME = "lenient"; /** Name of the 'rpcPriority' connection property. */ public static final String RPC_PRIORITY_NAME = "rpcPriority"; + /** Dialect to use for a connection. */ + private static final String DIALECT_PROPERTY_NAME = "dialect"; /** All valid connection properties. */ public static final Set VALID_PROPERTIES = @@ -236,6 +245,9 @@ public String[] getValidValues() { ConnectionProperty.createStringProperty( NUM_CHANNELS_PROPERTY_NAME, "The number of gRPC channels to use to communicate with Cloud Spanner. The default is 4."), + ConnectionProperty.createStringProperty( + CHANNEL_PROVIDER_PROPERTY_NAME, + "The name of the channel provider class. The name must reference an implementation of ExternalChannelProvider. If this property is not set, the connection will use the default grpc channel provider."), ConnectionProperty.createBooleanProperty( USE_PLAIN_TEXT_PROPERTY_NAME, "Use a plain text communication channel (i.e. non-TLS) for communicating with the server (true/false). Set this value to true for communication with the Cloud Spanner emulator.", @@ -259,7 +271,9 @@ public String[] getValidValues() { DEFAULT_LENIENT), ConnectionProperty.createStringProperty( RPC_PRIORITY_NAME, - "Sets the priority for all RPC invocations from this connection (HIGH/MEDIUM/LOW). The default is HIGH.")))); + "Sets the priority for all RPC invocations from this connection (HIGH/MEDIUM/LOW). The default is HIGH."), + ConnectionProperty.createStringProperty( + DIALECT_PROPERTY_NAME, "Sets the dialect to use for this connection.")))); private static final Set INTERNAL_PROPERTIES = Collections.unmodifiableSet( @@ -311,6 +325,15 @@ interface SpannerOptionsConfigurator { void configure(SpannerOptions.Builder options); } + /** + * {@link ExternalChannelProvider} can be used for to specify an external channel provider. This + * is needed if you require different certificates than those provided by the standard grpc + * channel provider. + */ + public interface ExternalChannelProvider { + TransportChannelProvider getChannelProvider(String host, int port); + } + /** Builder for {@link ConnectionOptions} instances. */ public static class Builder { private String uri; @@ -491,10 +514,12 @@ public static Builder newBuilder() { private final Credentials credentials; private final SessionPoolOptions sessionPoolOptions; private final Integer numChannels; + private final String channelProvider; private final Integer minSessions; private final Integer maxSessions; private final String userAgent; private final QueryOptions queryOptions; + private final Dialect dialect; private final boolean returnCommitStats; private final boolean autoConfigEmulator; private final RpcPriority rpcPriority; @@ -538,6 +563,14 @@ private ConnectionOptions(Builder builder) { queryOptionsBuilder.setOptimizerStatisticsPackage(parseOptimizerStatisticsPackage(this.uri)); this.queryOptions = queryOptionsBuilder.build(); this.returnCommitStats = parseReturnCommitStats(this.uri); + + try { + this.dialect = Dialect.fromName(parseDialect(uri)); + } catch (IllegalArgumentException e) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, e.getMessage(), e); + } + this.autoConfigEmulator = parseAutoConfigEmulator(this.uri); this.usePlainText = this.autoConfigEmulator || parseUsePlainText(this.uri); this.host = determineHost(matcher, autoConfigEmulator, usePlainText); @@ -569,6 +602,7 @@ private ConnectionOptions(Builder builder) { parseIntegerProperty(MAX_SESSIONS_PROPERTY_NAME, parseMaxSessions(builder.uri)); this.numChannels = parseIntegerProperty(NUM_CHANNELS_PROPERTY_NAME, parseNumChannels(builder.uri)); + this.channelProvider = parseChannelProvider(builder.uri); String projectId = matcher.group(Builder.PROJECT_GROUP); if (Builder.DEFAULT_PROJECT_ID_PLACEHOLDER.equalsIgnoreCase(projectId)) { @@ -699,6 +733,12 @@ static String parseNumChannels(String uri) { return value != null ? value : DEFAULT_NUM_CHANNELS; } + @VisibleForTesting + static String parseChannelProvider(String uri) { + String value = parseUriProperty(uri, CHANNEL_PROVIDER_PROPERTY_NAME); + return value != null ? value : DEFAULT_CHANNEL_PROVIDER; + } + @VisibleForTesting static String parseUserAgent(String uri) { String value = parseUriProperty(uri, USER_AGENT_PROPERTY_NAME); @@ -740,6 +780,12 @@ static RpcPriority parseRPCPriority(String uri) { return value != null ? RpcPriority.valueOf(value) : DEFAULT_RPC_PRIORITY; } + @VisibleForTesting + static String parseDialect(String uri) { + String value = parseUriProperty(uri, DIALECT_PROPERTY_NAME); + return value != null ? value.toUpperCase() : DEFAULT_DIALECT; + } + @VisibleForTesting static String parseUriProperty(String uri, String property) { Pattern pattern = Pattern.compile(String.format("(?is)(?:;|\\?)%s=(.*?)(?:;|$)", property)); @@ -845,6 +891,25 @@ public Integer getNumChannels() { return numChannels; } + /** Calls the getChannelProvider() method from the supplied class. */ + public TransportChannelProvider getChannelProvider() { + if (channelProvider == null) { + return null; + } + try { + URL url = new URL(host); + ExternalChannelProvider provider = + ExternalChannelProvider.class.cast(Class.forName(channelProvider).newInstance()); + return provider.getChannelProvider(url.getHost(), url.getPort()); + } catch (Exception e) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, + String.format( + "%s : Failed to create channel with external provider: %s", + e.toString(), channelProvider)); + } + } + /** The host and port number that this {@link ConnectionOptions} will connect to */ public String getHost() { return host; @@ -905,6 +970,11 @@ public String getWarnings() { return warnings; } + /** The dialect to use for connections created by this {@link ConnectionOptions}. */ + public Dialect getDialect() { + return dialect; + } + /** Use http instead of https. Only valid for (local) test servers. */ boolean isUsePlainText() { return usePlainText; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlBatch.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlBatch.java index 675b6e3a955..6d34c76fde8 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlBatch.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlBatch.java @@ -16,6 +16,8 @@ package com.google.cloud.spanner.connection; +import static com.google.cloud.spanner.connection.AbstractStatementParser.RUN_BATCH_STATEMENT; + import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; import com.google.api.gax.longrunning.OperationFuture; @@ -29,10 +31,9 @@ import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; -import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.cloud.spanner.connection.Connection.InternalMetadataQuery; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; -import com.google.cloud.spanner.connection.StatementParser.StatementType; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.spanner.admin.database.v1.DatabaseAdminGrpc; @@ -210,15 +211,6 @@ public ApiFuture writeAsync(Iterable mutations) { ErrorCode.FAILED_PRECONDITION, "Writing mutations is not allowed for DDL batches."); } - /** - * Create a {@link ParsedStatement} that we can use as input for the generic execute method when - * the {@link #runBatch()} method is executed. This method uses the generic execute method that - * allows statements to be cancelled and to timeout, which requires the input to be a {@link - * ParsedStatement}. - */ - private static final ParsedStatement RUN_BATCH = - StatementParser.INSTANCE.parse(Statement.of("RUN BATCH")); - @Override public ApiFuture runBatchAsync() { ConnectionPreconditions.checkState( @@ -235,7 +227,7 @@ public ApiFuture runBatchAsync() { ddlClient.executeDdl(statements); try { // Wait until the operation has finished. - getWithStatementTimeout(operation, RUN_BATCH); + getWithStatementTimeout(operation, RUN_BATCH_STATEMENT); long[] updateCounts = new long[statements.size()]; Arrays.fill(updateCounts, 1L); state = UnitOfWorkState.RAN; @@ -252,7 +244,7 @@ public ApiFuture runBatchAsync() { }; this.state = UnitOfWorkState.RUNNING; return executeStatementAsync( - RUN_BATCH, callable, DatabaseAdminGrpc.getUpdateDatabaseDdlMethod()); + RUN_BATCH_STATEMENT, callable, DatabaseAdminGrpc.getUpdateDatabaseDdlMethod()); } long[] extractUpdateCounts(OperationFuture operation) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DmlBatch.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DmlBatch.java index d7bf7302434..d2224f98ad3 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DmlBatch.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DmlBatch.java @@ -29,8 +29,8 @@ import com.google.cloud.spanner.Options.UpdateOption; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerExceptionFactory; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; -import com.google.cloud.spanner.connection.StatementParser.StatementType; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.MoreExecutors; import java.util.ArrayList; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedBatchUpdate.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedBatchUpdate.java index 6721e9b6eca..42f270d9f85 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedBatchUpdate.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedBatchUpdate.java @@ -16,6 +16,8 @@ package com.google.cloud.spanner.connection; +import static com.google.cloud.spanner.connection.AbstractStatementParser.RUN_BATCH_STATEMENT; + import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.SpannerBatchUpdateException; import com.google.cloud.spanner.SpannerException; @@ -53,9 +55,7 @@ public void retry(AbortedException aborted) throws AbortedException { transaction .getStatementExecutor() .invokeInterceptors( - ReadWriteTransaction.EXECUTE_BATCH_UPDATE_STATEMENT, - StatementExecutionStep.RETRY_STATEMENT, - transaction); + RUN_BATCH_STATEMENT, StatementExecutionStep.RETRY_STATEMENT, transaction); try { transaction.getReadContext().batchUpdate(statements); } catch (AbortedException e) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedQuery.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedQuery.java index 4a1e1b005ce..d64c4b9401f 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedQuery.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedQuery.java @@ -21,8 +21,8 @@ import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.ReadWriteTransaction.RetriableStatement; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; import com.google.common.base.Preconditions; import java.util.Objects; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedUpdate.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedUpdate.java index 836185fabeb..5c184e20d3b 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedUpdate.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/FailedUpdate.java @@ -19,8 +19,8 @@ import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.ReadWriteTransaction.RetriableStatement; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; import com.google.common.base.Preconditions; import java.util.Objects; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/PostgreSQLStatementParser.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/PostgreSQLStatementParser.java new file mode 100644 index 00000000000..0b29bec5333 --- /dev/null +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/PostgreSQLStatementParser.java @@ -0,0 +1,256 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner.connection; + +import com.google.api.core.InternalApi; +import com.google.cloud.spanner.Dialect; +import com.google.cloud.spanner.ErrorCode; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.common.base.Preconditions; + +@InternalApi +public class PostgreSQLStatementParser extends AbstractStatementParser { + PostgreSQLStatementParser() { + super(Dialect.POSTGRESQL); + } + + /** + * Indicates whether the parser supports the {@code EXPLAIN} clause. The PostgreSQL parser does + * not support it. + */ + @Override + protected boolean supportsExplain() { + return false; + } + + /** + * Removes comments from and trims the given sql statement. PostgreSQL supports two types of + * comments: + * + *
    + *
  • Single line comments starting with '--' + *
  • Multi line comments between '/*' and '*/'. Nested comments are supported and all + * comments, including the nested comments, must be terminated. + *
+ * + * Reference: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-COMMENTS + * + * @param sql The sql statement to remove comments from and to trim. + * @return the sql statement without the comments and leading and trailing spaces. + */ + @InternalApi + @Override + String removeCommentsAndTrimInternal(String sql) { + Preconditions.checkNotNull(sql); + String currentTag = null; + boolean isInQuoted = false; + boolean isInSingleLineComment = false; + int multiLineCommentLevel = 0; + char startQuote = 0; + boolean lastCharWasEscapeChar = false; + StringBuilder res = new StringBuilder(sql.length()); + int index = 0; + while (index < sql.length()) { + char c = sql.charAt(index); + if (isInQuoted) { + if ((c == '\n' || c == '\r') && startQuote != DOLLAR) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); + } else if (c == startQuote) { + if (c == DOLLAR) { + // Check if this is the end of the current dollar quoted string. + String tag = parseDollarQuotedString(sql, index + 1); + if (tag != null && tag.equals(currentTag)) { + index += tag.length() + 1; + res.append(c); + res.append(tag); + isInQuoted = false; + startQuote = 0; + } + } else if (lastCharWasEscapeChar) { + lastCharWasEscapeChar = false; + } else if (sql.length() > index + 1 && sql.charAt(index + 1) == startQuote) { + // This is an escaped quote (e.g. 'foo''bar') + res.append(c); + index++; + } else { + isInQuoted = false; + startQuote = 0; + } + } else if (c == '\\') { + lastCharWasEscapeChar = true; + } else { + lastCharWasEscapeChar = false; + } + res.append(c); + } else { + // We are not in a quoted string. + if (isInSingleLineComment) { + if (c == '\n') { + isInSingleLineComment = false; + // Include the line feed in the result. + res.append(c); + } + } else if (multiLineCommentLevel > 0) { + if (sql.length() > index + 1 && c == ASTERIKS && sql.charAt(index + 1) == SLASH) { + multiLineCommentLevel--; + index++; + } else if (sql.length() > index + 1 && c == SLASH && sql.charAt(index + 1) == ASTERIKS) { + multiLineCommentLevel++; + index++; + } + } else { + // Check for -- which indicates the start of a single-line comment. + if (sql.length() > index + 1 && c == HYPHEN && sql.charAt(index + 1) == HYPHEN) { + // This is a single line comment. + isInSingleLineComment = true; + } else if (sql.length() > index + 1 && c == SLASH && sql.charAt(index + 1) == ASTERIKS) { + multiLineCommentLevel++; + index++; + } else { + if (c == SINGLE_QUOTE || c == DOUBLE_QUOTE) { + isInQuoted = true; + startQuote = c; + } else if (c == DOLLAR) { + currentTag = parseDollarQuotedString(sql, index + 1); + if (currentTag != null) { + isInQuoted = true; + startQuote = DOLLAR; + index += currentTag.length() + 1; + res.append(c); + res.append(currentTag); + } + } + res.append(c); + } + } + } + index++; + } + if (isInQuoted) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); + } + if (multiLineCommentLevel > 0) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, + "SQL statement contains an unterminated block comment: " + sql); + } + if (res.length() > 0 && res.charAt(res.length() - 1) == ';') { + res.deleteCharAt(res.length() - 1); + } + return res.toString().trim(); + } + + String parseDollarQuotedString(String sql, int index) { + // Look ahead to the next dollar sign (if any). Everything in between is the quote tag. + StringBuilder tag = new StringBuilder(); + while (index < sql.length()) { + char c = sql.charAt(index); + if (c == DOLLAR) { + return tag.toString(); + } + if (!Character.isJavaIdentifierPart(c)) { + break; + } + tag.append(c); + index++; + } + return null; + } + + /** PostgreSQL does not support statement hints. */ + @Override + String removeStatementHint(String sql) { + return sql; + } + + @InternalApi + @Override + ParametersInfo convertPositionalParametersToNamedParametersInternal(char paramChar, String sql) { + Preconditions.checkNotNull(sql); + final String namedParamPrefix = "$"; + String currentTag = null; + boolean isInQuoted = false; + char startQuote = 0; + boolean lastCharWasEscapeChar = false; + StringBuilder named = new StringBuilder(sql.length() + countOccurrencesOf(paramChar, sql)); + int index = 0; + int paramIndex = 1; + while (index < sql.length()) { + char c = sql.charAt(index); + if (isInQuoted) { + if ((c == '\n' || c == '\r') && startQuote != DOLLAR) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); + } else if (c == startQuote) { + if (c == DOLLAR) { + // Check if this is the end of the current dollar quoted string. + String tag = parseDollarQuotedString(sql, index + 1); + if (tag != null && tag.equals(currentTag)) { + index += tag.length() + 1; + named.append(c); + named.append(tag); + isInQuoted = false; + startQuote = 0; + } + } else if (lastCharWasEscapeChar) { + lastCharWasEscapeChar = false; + } else if (sql.length() > index + 1 && sql.charAt(index + 1) == startQuote) { + // This is an escaped quote (e.g. 'foo''bar') + named.append(c); + index++; + } else { + isInQuoted = false; + startQuote = 0; + } + } else if (c == '\\') { + lastCharWasEscapeChar = true; + } else { + lastCharWasEscapeChar = false; + } + named.append(c); + } else { + if (c == paramChar) { + named.append(namedParamPrefix + paramIndex); + paramIndex++; + } else { + if (c == SINGLE_QUOTE || c == DOUBLE_QUOTE) { + isInQuoted = true; + startQuote = c; + } else if (c == DOLLAR) { + currentTag = parseDollarQuotedString(sql, index + 1); + if (currentTag != null) { + isInQuoted = true; + startQuote = DOLLAR; + index += currentTag.length() + 1; + named.append(c); + named.append(currentTag); + } + } + named.append(c); + } + } + index++; + } + if (isInQuoted) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); + } + return new ParametersInfo(paramIndex - 1, named.toString()); + } +} diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadOnlyTransaction.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadOnlyTransaction.java index 1e1fa0cba86..f4731336674 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadOnlyTransaction.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadOnlyTransaction.java @@ -28,7 +28,7 @@ import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.TimestampBound; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.common.base.Preconditions; /** diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java index 45b49de19b3..822eb3b0169 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ReadWriteTransaction.java @@ -17,6 +17,10 @@ package com.google.cloud.spanner.connection; import static com.google.cloud.spanner.SpannerApiFutures.get; +import static com.google.cloud.spanner.connection.AbstractStatementParser.BEGIN_STATEMENT; +import static com.google.cloud.spanner.connection.AbstractStatementParser.COMMIT_STATEMENT; +import static com.google.cloud.spanner.connection.AbstractStatementParser.ROLLBACK_STATEMENT; +import static com.google.cloud.spanner.connection.AbstractStatementParser.RUN_BATCH_STATEMENT; import static com.google.common.base.Preconditions.checkNotNull; import com.google.api.core.ApiFuture; @@ -40,7 +44,7 @@ import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TransactionContext; import com.google.cloud.spanner.TransactionManager; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.TransactionRetryListener.RetryResult; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; @@ -203,9 +207,6 @@ public boolean isReadOnly() { return false; } - private static final ParsedStatement BEGIN_STATEMENT = - StatementParser.INSTANCE.parse(Statement.of("BEGIN")); - @Override void checkValidTransaction() { checkValidState(); @@ -453,20 +454,6 @@ public void onSuccess(Long result) {} return res; } - /** - * Create a RUN BATCH statement to use with the {@link #executeBatchUpdate(Iterable)} method to - * allow it to be cancelled, time out or retried. - * - *

{@link ReadWriteTransaction} uses the generic methods {@link #executeAsync(ParsedStatement, - * Callable)} and {@link #runWithRetry(Callable)} to allow statements to be cancelled, to timeout - * and to be retried. These methods require a {@link ParsedStatement} as input. When the {@link - * #executeBatchUpdate(Iterable)} method is called, we do not have one {@link ParsedStatement}, - * and the method uses this statement instead in order to use the same logic as the other - * statements. - */ - static final ParsedStatement EXECUTE_BATCH_UPDATE_STATEMENT = - StatementParser.INSTANCE.parse(Statement.of("RUN BATCH")); - @Override public ApiFuture executeBatchUpdateAsync( Iterable updates, final UpdateOption... options) { @@ -484,7 +471,7 @@ public ApiFuture executeBatchUpdateAsync( if (retryAbortsInternally) { res = executeStatementAsync( - EXECUTE_BATCH_UPDATE_STATEMENT, + RUN_BATCH_STATEMENT, () -> { checkTimedOut(); return runWithRetry( @@ -492,7 +479,7 @@ public ApiFuture executeBatchUpdateAsync( try { getStatementExecutor() .invokeInterceptors( - EXECUTE_BATCH_UPDATE_STATEMENT, + RUN_BATCH_STATEMENT, StatementExecutionStep.EXECUTE_STATEMENT, ReadWriteTransaction.this); long[] updateCounts = @@ -513,7 +500,7 @@ public ApiFuture executeBatchUpdateAsync( } else { res = executeStatementAsync( - EXECUTE_BATCH_UPDATE_STATEMENT, + RUN_BATCH_STATEMENT, () -> { checkTimedOut(); checkAborted(); @@ -548,19 +535,6 @@ public ApiFuture writeAsync(Iterable mutations) { return ApiFutures.immediateFuture(null); } - /** - * Create a COMMIT statement to use with the {@link #commit()} method to allow it to be cancelled, - * time out or retried. - * - *

{@link ReadWriteTransaction} uses the generic methods {@link #executeAsync(ParsedStatement, - * Callable)} and {@link #runWithRetry(Callable)} to allow statements to be cancelled, to timeout - * and to be retried. These methods require a {@link ParsedStatement} as input. When the {@link - * #commit()} method is called directly, we do not have a {@link ParsedStatement}, and the method - * uses this statement instead in order to use the same logic as the other statements. - */ - private static final ParsedStatement COMMIT_STATEMENT = - StatementParser.INSTANCE.parse(Statement.of("COMMIT")); - private final Callable commitCallable = new Callable() { @Override @@ -861,10 +835,6 @@ private void invokeTransactionRetryListenersOnFinish(RetryResult result) { } } - /** The {@link Statement} and {@link Callable} for rollbacks */ - private final ParsedStatement rollbackStatement = - StatementParser.INSTANCE.parse(Statement.of("ROLLBACK")); - private final Callable rollbackCallable = new Callable() { @Override @@ -890,7 +860,7 @@ public ApiFuture rollbackAsync() { state = UnitOfWorkState.ROLLED_BACK; if (txContextFuture != null && state != UnitOfWorkState.ABORTED) { return executeStatementAsync( - rollbackStatement, rollbackCallable, SpannerGrpc.getRollbackMethod()); + ROLLBACK_STATEMENT, rollbackCallable, SpannerGrpc.getRollbackMethod()); } else { return ApiFutures.immediateFuture(null); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableBatchUpdate.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableBatchUpdate.java index ad2e2b2950f..194200faae2 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableBatchUpdate.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableBatchUpdate.java @@ -16,6 +16,8 @@ package com.google.cloud.spanner.connection; +import static com.google.cloud.spanner.connection.AbstractStatementParser.RUN_BATCH_STATEMENT; + import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.Options.UpdateOption; import com.google.cloud.spanner.SpannerException; @@ -55,9 +57,7 @@ public void retry(AbortedException aborted) throws AbortedException { transaction .getStatementExecutor() .invokeInterceptors( - ReadWriteTransaction.EXECUTE_BATCH_UPDATE_STATEMENT, - StatementExecutionStep.RETRY_STATEMENT, - transaction); + RUN_BATCH_STATEMENT, StatementExecutionStep.RETRY_STATEMENT, transaction); newCount = transaction.getReadContext().batchUpdate(statements, options); } catch (AbortedException e) { // Just re-throw the AbortedException and let the retry logic determine whether another try diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableUpdate.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableUpdate.java index 060a1aa61de..3818bdd739c 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableUpdate.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/RetriableUpdate.java @@ -20,8 +20,8 @@ import com.google.cloud.spanner.Options.UpdateOption; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.ReadWriteTransaction.RetriableStatement; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; import com.google.common.base.Preconditions; /** diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SingleUseTransaction.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SingleUseTransaction.java index aca72d09680..f34e6f72e71 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SingleUseTransaction.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SingleUseTransaction.java @@ -16,6 +16,9 @@ package com.google.cloud.spanner.connection; +import static com.google.cloud.spanner.connection.AbstractStatementParser.COMMIT_STATEMENT; +import static com.google.cloud.spanner.connection.AbstractStatementParser.RUN_BATCH_STATEMENT; + import com.google.api.core.ApiFuture; import com.google.api.core.SettableApiFuture; import com.google.api.gax.longrunning.OperationFuture; @@ -33,11 +36,10 @@ import com.google.cloud.spanner.SpannerBatchUpdateException; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; -import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.TransactionRunner; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; -import com.google.cloud.spanner.connection.StatementParser.StatementType; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -304,9 +306,6 @@ public ApiFuture executeUpdateAsync(ParsedStatement update, UpdateOption.. return res; } - private final ParsedStatement executeBatchUpdateStatement = - StatementParser.INSTANCE.parse(Statement.of("RUN BATCH")); - @Override public ApiFuture executeBatchUpdateAsync( Iterable updates, UpdateOption... options) { @@ -417,12 +416,9 @@ private ApiFuture executeTransactionalBatchUpdateAsync( }); }; return executeStatementAsync( - executeBatchUpdateStatement, callable, SpannerGrpc.getExecuteBatchDmlMethod()); + RUN_BATCH_STATEMENT, callable, SpannerGrpc.getExecuteBatchDmlMethod()); } - private final ParsedStatement commitStatement = - StatementParser.INSTANCE.parse(Statement.of("COMMIT")); - @Override public ApiFuture writeAsync(final Iterable mutations) { Preconditions.checkNotNull(mutations); @@ -447,7 +443,7 @@ public ApiFuture writeAsync(final Iterable mutations) { throw t; } }; - return executeStatementAsync(commitStatement, callable, SpannerGrpc.getCommitMethod()); + return executeStatementAsync(COMMIT_STATEMENT, callable, SpannerGrpc.getCommitMethod()); } @Override diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java index 3d433adf87d..479b10df2e5 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java @@ -17,6 +17,7 @@ package com.google.cloud.spanner.connection; import com.google.cloud.NoCredentials; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.SessionPoolOptions; import com.google.cloud.spanner.Spanner; @@ -152,6 +153,7 @@ static class SpannerPoolKey { private final Integer numChannels; private final boolean usePlainText; private final String userAgent; + private final Dialect dialect; @VisibleForTesting static SpannerPoolKey of(ConnectionOptions options) { @@ -169,6 +171,7 @@ private SpannerPoolKey(ConnectionOptions options) { this.numChannels = options.getNumChannels(); this.usePlainText = options.isUsePlainText(); this.userAgent = options.getUserAgent(); + this.dialect = options.getDialect(); } @Override @@ -183,7 +186,8 @@ public boolean equals(Object o) { && Objects.equals(this.sessionPoolOptions, other.sessionPoolOptions) && Objects.equals(this.numChannels, other.numChannels) && Objects.equals(this.usePlainText, other.usePlainText) - && Objects.equals(this.userAgent, other.userAgent); + && Objects.equals(this.userAgent, other.userAgent) + && Objects.equals(this.dialect, other.dialect); } @Override @@ -195,7 +199,8 @@ public int hashCode() { this.sessionPoolOptions, this.numChannels, this.usePlainText, - this.userAgent); + this.userAgent, + this.dialect); } } @@ -321,11 +326,15 @@ Spanner createSpanner(SpannerPoolKey key, ConnectionOptions options) { .setClientLibToken(MoreObjects.firstNonNull(key.userAgent, CONNECTION_API_CLIENT_LIB_TOKEN)) .setHost(key.host) .setProjectId(key.projectId) - .setCredentials(options.getCredentials()); + .setCredentials(options.getCredentials()) + .setDialect(options.getDialect()); builder.setSessionPoolOption(key.sessionPoolOptions); if (key.numChannels != null) { builder.setNumChannels(key.numChannels); } + if (options.getChannelProvider() != null) { + builder.setChannelProvider(options.getChannelProvider()); + } if (key.usePlainText) { // Credentials may not be sent over a plain text channel. builder.setCredentials(NoCredentials.getInstance()); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerStatementParser.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerStatementParser.java new file mode 100644 index 00000000000..a9c7624f273 --- /dev/null +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerStatementParser.java @@ -0,0 +1,249 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner.connection; + +import com.google.api.core.InternalApi; +import com.google.cloud.spanner.Dialect; +import com.google.cloud.spanner.ErrorCode; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.common.base.Preconditions; +import com.google.common.collect.Sets; +import java.util.Set; + +@InternalApi +public class SpannerStatementParser extends AbstractStatementParser { + + public SpannerStatementParser() { + super(Dialect.GOOGLE_STANDARD_SQL); + } + + /** + * Indicates whether the parser supports the {@code EXPLAIN} clause. The Spanner parser does + * support it. + */ + @Override + protected boolean supportsExplain() { + return true; + } + + /** + * Removes comments from and trims the given sql statement. Spanner supports three types of + * comments: + * + *

    + *
  • Single line comments starting with '--' + *
  • Single line comments starting with '#' + *
  • Multi line comments between '/*' and '*/' + *
+ * + * Reference: https://cloud.google.com/spanner/docs/lexical#comments + * + * @param sql The sql statement to remove comments from and to trim. + * @return the sql statement without the comments and leading and trailing spaces. + */ + @InternalApi + @Override + String removeCommentsAndTrimInternal(String sql) { + Preconditions.checkNotNull(sql); + boolean isInQuoted = false; + boolean isInSingleLineComment = false; + boolean isInMultiLineComment = false; + char startQuote = 0; + boolean lastCharWasEscapeChar = false; + boolean isTripleQuoted = false; + StringBuilder res = new StringBuilder(sql.length()); + int index = 0; + while (index < sql.length()) { + char c = sql.charAt(index); + if (isInQuoted) { + if ((c == '\n' || c == '\r') && !isTripleQuoted) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); + } else if (c == startQuote) { + if (lastCharWasEscapeChar) { + // TODO: Is this correct inside of a triple-quoted string? + lastCharWasEscapeChar = false; + } else if (isTripleQuoted) { + if (sql.length() > index + 2 + && sql.charAt(index + 1) == startQuote + && sql.charAt(index + 2) == startQuote) { + isInQuoted = false; + startQuote = 0; + isTripleQuoted = false; + res.append(c).append(c); + index += 2; + } + } else { + isInQuoted = false; + startQuote = 0; + } + } else if (c == '\\') { + lastCharWasEscapeChar = true; + } else { + lastCharWasEscapeChar = false; + } + res.append(c); + } else { + // We are not in a quoted string. + if (isInSingleLineComment) { + if (c == '\n') { + isInSingleLineComment = false; + // Include the line feed in the result. + res.append(c); + } + } else if (isInMultiLineComment) { + if (sql.length() > index + 1 && c == ASTERIKS && sql.charAt(index + 1) == SLASH) { + isInMultiLineComment = false; + index++; + } + } else { + if (c == DASH + || (sql.length() > index + 1 && c == HYPHEN && sql.charAt(index + 1) == HYPHEN)) { + // This is a single line comment. + isInSingleLineComment = true; + } else if (sql.length() > index + 1 && c == SLASH && sql.charAt(index + 1) == ASTERIKS) { + isInMultiLineComment = true; + index++; + } else { + if (c == SINGLE_QUOTE || c == DOUBLE_QUOTE || c == BACKTICK_QUOTE) { + isInQuoted = true; + startQuote = c; + // Check whether it is a triple-quote. + if (sql.length() > index + 2 + && sql.charAt(index + 1) == startQuote + && sql.charAt(index + 2) == startQuote) { + isTripleQuoted = true; + res.append(c).append(c); + index += 2; + } + } + res.append(c); + } + } + } + index++; + } + if (isInQuoted) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); + } + if (res.length() > 0 && res.charAt(res.length() - 1) == ';') { + res.deleteCharAt(res.length() - 1); + } + return res.toString().trim(); + } + + /** Removes any statement hints at the beginning of the statement. */ + @Override + String removeStatementHint(String sql) { + // Valid statement hints at the beginning of a query statement can only contain a fixed set of + // possible values. Although it is possible to add a @{FORCE_INDEX=...} as a statement hint, the + // only allowed value is _BASE_TABLE. This means that we can safely assume that the statement + // hint will not contain any special characters, for example a closing curly brace or one of the + // keywords SELECT, UPDATE, DELETE, WITH, and that we can keep the check simple by just + // searching for the first occurrence of a keyword that should be preceded by a closing curly + // brace at the end of the statement hint. + int startStatementHintIndex = sql.indexOf('{'); + // Statement hints are allowed for both queries and DML statements. + int startQueryIndex = -1; + String upperCaseSql = sql.toUpperCase(); + Set selectAndDmlStatements = + Sets.union(selectStatements, dmlStatements).immutableCopy(); + for (String keyword : selectAndDmlStatements) { + startQueryIndex = upperCaseSql.indexOf(keyword); + if (startQueryIndex > -1) { + break; + } + } + if (startQueryIndex > -1) { + int endStatementHintIndex = sql.substring(0, startQueryIndex).lastIndexOf('}'); + if (startStatementHintIndex == -1 || startStatementHintIndex > endStatementHintIndex) { + // Looks like an invalid statement hint. Just ignore at this point and let the caller handle + // the invalid query. + return sql; + } + return removeCommentsAndTrim(sql.substring(endStatementHintIndex + 1)); + } + // Seems invalid, just return the original statement. + return sql; + } + + @InternalApi + @Override + ParametersInfo convertPositionalParametersToNamedParametersInternal(char paramChar, String sql) { + final char SINGLE_QUOTE = '\''; + final char DOUBLE_QUOTE = '"'; + final char BACKTICK_QUOTE = '`'; + boolean isInQuoted = false; + char startQuote = 0; + boolean lastCharWasEscapeChar = false; + boolean isTripleQuoted = false; + int paramIndex = 1; + StringBuilder named = new StringBuilder(sql.length() + countOccurrencesOf(paramChar, sql)); + for (int index = 0; index < sql.length(); index++) { + char c = sql.charAt(index); + if (isInQuoted) { + if ((c == '\n' || c == '\r') && !isTripleQuoted) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); + } else if (c == startQuote) { + if (lastCharWasEscapeChar) { + lastCharWasEscapeChar = false; + } else if (isTripleQuoted) { + if (sql.length() > index + 2 + && sql.charAt(index + 1) == startQuote + && sql.charAt(index + 2) == startQuote) { + isInQuoted = false; + startQuote = 0; + isTripleQuoted = false; + } + } else { + isInQuoted = false; + startQuote = 0; + } + } else if (c == '\\') { + lastCharWasEscapeChar = true; + } else { + lastCharWasEscapeChar = false; + } + named.append(c); + } else { + if (c == paramChar) { + named.append("@p" + paramIndex); + paramIndex++; + } else { + if (c == SINGLE_QUOTE || c == DOUBLE_QUOTE || c == BACKTICK_QUOTE) { + isInQuoted = true; + startQuote = c; + // check whether it is a triple-quote + if (sql.length() > index + 2 + && sql.charAt(index + 1) == startQuote + && sql.charAt(index + 2) == startQuote) { + isTripleQuoted = true; + } + } + named.append(c); + } + } + } + if (isInQuoted) { + throw SpannerExceptionFactory.newSpannerException( + ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); + } + return new ParametersInfo(paramIndex - 1, named.toString()); + } +} diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutionInterceptor.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutionInterceptor.java index 159edc3e3d4..a2eaa99a5cb 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutionInterceptor.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutionInterceptor.java @@ -17,7 +17,7 @@ package com.google.cloud.spanner.connection; import com.google.cloud.spanner.ResultSet; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; /** Interface for interceptors that are invoked before a statement is executed. */ interface StatementExecutionInterceptor { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutor.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutor.java index 821ebb1f288..438fc749fdc 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutor.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementExecutor.java @@ -18,8 +18,8 @@ import com.google.api.core.ApiFuture; import com.google.api.core.ListenableFutureToApiFuture; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.ReadOnlyStalenessUtil.DurationValueGetter; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.ListeningExecutorService; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/UnitOfWork.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/UnitOfWork.java index 0bf6fff9f27..cf68f4ddaf3 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/UnitOfWork.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/UnitOfWork.java @@ -27,7 +27,7 @@ import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.TransactionContext; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.spanner.v1.ResultSetStats; import java.util.concurrent.ExecutionException; diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java index 4558559faa2..98a7e0927f3 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java @@ -175,6 +175,8 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; @@ -187,6 +189,8 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nullable; import org.threeten.bp.Duration; @@ -578,18 +582,19 @@ private static void maybeEnableGrpcGcpExtension( } private static HeaderProvider headerProviderWithUserAgentFrom(HeaderProvider headerProvider) { + final Optional> existingUserAgentEntry = + headerProvider.getHeaders().entrySet().stream() + .filter(entry -> entry.getKey().equalsIgnoreCase(USER_AGENT_KEY)) + .findFirst(); + final String existingUserAgentValue = existingUserAgentEntry.map(Entry::getValue).orElse(null); + final String userAgent = + Stream.of(existingUserAgentValue, DEFAULT_USER_AGENT) + .filter(Objects::nonNull) + .collect(Collectors.joining(" ")); + final Map headersWithUserAgent = new HashMap<>(headerProvider.getHeaders()); - String userAgent = null; - for (Entry entry : headersWithUserAgent.entrySet()) { - if (entry.getKey().equalsIgnoreCase(USER_AGENT_KEY)) { - userAgent = entry.getValue(); - headersWithUserAgent.remove(entry.getKey()); - break; - } - } - headersWithUserAgent.put( - USER_AGENT_KEY, - userAgent == null ? DEFAULT_USER_AGENT : userAgent + " " + DEFAULT_USER_AGENT); + existingUserAgentEntry.ifPresent(entry -> headersWithUserAgent.remove(entry.getKey())); + headersWithUserAgent.put(USER_AGENT_KEY, userAgent); return FixedHeaderProvider.create(headersWithUserAgent); } @@ -1045,9 +1050,7 @@ public OperationFuture createDatabase( Iterable additionalStatements, com.google.cloud.spanner.Database databaseInfo) throws SpannerException { - final String databaseId = - createDatabaseStatement.substring( - "CREATE DATABASE `".length(), createDatabaseStatement.length() - 1); + final String databaseId = databaseInfo.getId().getDatabase(); CreateDatabaseRequest.Builder requestBuilder = CreateDatabaseRequest.newBuilder() .setParent(instanceName) @@ -1057,6 +1060,9 @@ public OperationFuture createDatabase( requestBuilder.setEncryptionConfig( EncryptionConfigProtoMapper.encryptionConfig(databaseInfo.getEncryptionConfig())); } + if (databaseInfo.getDialect() != null) { + requestBuilder.setDatabaseDialect(databaseInfo.getDialect().toProto()); + } final CreateDatabaseRequest request = requestBuilder.build(); OperationFutureCallable callable = diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/testing/RemoteSpannerHelper.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/testing/RemoteSpannerHelper.java index f6021b2a7d6..b3e9abf0740 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/testing/RemoteSpannerHelper.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/testing/RemoteSpannerHelper.java @@ -20,14 +20,18 @@ import com.google.cloud.spanner.BatchClient; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.InstanceId; import com.google.cloud.spanner.Spanner; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.SpannerOptions; +import com.google.common.collect.Iterables; import com.google.spanner.admin.database.v1.CreateDatabaseMetadata; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; @@ -93,7 +97,7 @@ public InstanceId getInstanceId() { * accordingly. */ public Database createTestDatabase(String... statements) throws SpannerException { - return createTestDatabase(Arrays.asList(statements)); + return createTestDatabase(Dialect.GOOGLE_STANDARD_SQL, Arrays.asList(statements)); } /** @@ -115,14 +119,28 @@ public String getUniqueBackupId() { * DATABASE ...} statement should not be included; an appropriate name will be chosen and the * statement generated accordingly. */ - public Database createTestDatabase(Iterable statements) throws SpannerException { + public Database createTestDatabase(Dialect dialect, Iterable statements) + throws SpannerException { String dbId = getUniqueDatabaseId(); + Database databaseToCreate = + client + .getDatabaseAdminClient() + .newDatabaseBuilder( + DatabaseId.of(instanceId.getProject(), instanceId.getInstance(), dbId)) + .setDialect(dialect) + .build(); try { + Iterable ddlStatements = + dialect == Dialect.POSTGRESQL ? Collections.emptyList() : statements; OperationFuture op = - client - .getDatabaseAdminClient() - .createDatabase(instanceId.getInstance(), dbId, statements); + client.getDatabaseAdminClient().createDatabase(databaseToCreate, ddlStatements); Database db = op.get(); + if (dialect == Dialect.POSTGRESQL && Iterables.size(statements) > 0) { + client + .getDatabaseAdminClient() + .updateDatabaseDdl(instanceId.getInstance(), dbId, statements, null) + .get(); + } logger.log(Level.FINE, "Created test database {0}", db.getId()); dbs.add(db); return db; @@ -131,6 +149,10 @@ public Database createTestDatabase(Iterable statements) throws SpannerEx } } + public Database createTestDatabase(Iterable statements) throws SpannerException { + return createTestDatabase(Dialect.GOOGLE_STANDARD_SQL, statements); + } + /** Deletes all the databases created via {@code createTestDatabase}. Shuts down the client. */ public void cleanUp() { // Drop all the databases we created explicitly. diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java index 7bb8bb51943..10167ddc9d0 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/AbstractStructReaderTypesTest.java @@ -200,6 +200,13 @@ public static Collection parameters() { "getBigDecimal", Collections.singletonList("getValue") }, + { + Type.pgNumeric(), + "getStringInternal", + "1.23", + "getString", + Collections.singletonList("getValue") + }, { Type.string(), "getStringInternal", @@ -284,6 +291,13 @@ public static Collection parameters() { "getBigDecimalList", Collections.singletonList("getValue") }, + { + Type.array(Type.pgNumeric()), + "getStringListInternal", + Arrays.asList("1.23", "2.34"), + "getStringList", + Collections.singletonList("getValue") + }, { Type.array(Type.string()), "getStringListInternal", diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java index 4d44861b75b..44a531d4a34 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseAdminClientImplTest.java @@ -17,6 +17,7 @@ package com.google.cloud.spanner; import static com.google.common.truth.Truth.assertThat; +import static com.google.spanner.admin.database.v1.DatabaseDialect.GOOGLE_STANDARD_SQL; import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -46,6 +47,7 @@ import com.google.spanner.admin.database.v1.CreateBackupMetadata; import com.google.spanner.admin.database.v1.CreateDatabaseMetadata; import com.google.spanner.admin.database.v1.Database; +import com.google.spanner.admin.database.v1.DatabaseDialect; import com.google.spanner.admin.database.v1.EncryptionInfo; import com.google.spanner.admin.database.v1.RestoreDatabaseMetadata; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; @@ -77,6 +79,7 @@ public class DatabaseAdminClientImplTest { private static final String KMS_KEY_NAME = "projects/my-project/locations/some-location/keyRings/my-keyring/cryptoKeys/my-key"; private static final String KMS_KEY_VERSION = "1"; + private static final DatabaseDialect DIALECT = GOOGLE_STANDARD_SQL; @Mock SpannerRpc rpc; DatabaseAdminClientImpl client; @@ -93,6 +96,7 @@ private Database getDatabaseProto() { .setState(Database.State.READY) .setEarliestVersionTime(EARLIEST_VERSION_TIME.toProto()) .setVersionRetentionPeriod(VERSION_RETENTION_PERIOD) + .setDatabaseDialect(DIALECT) .build(); } @@ -161,8 +165,11 @@ public void createDatabase() throws Exception { INSTANCE_NAME, "CREATE DATABASE `" + DB_ID + "`", Collections.emptyList(), - new com.google.cloud.spanner.Database( - DatabaseId.of(DB_NAME), State.UNSPECIFIED, client))) + client + .newDatabaseBuilder(DatabaseId.of(DB_NAME)) + .setState(State.UNSPECIFIED) + .setDialect(Dialect.GOOGLE_STANDARD_SQL) + .build())) .thenReturn(rawOperationFuture); OperationFuture op = client.createDatabase(INSTANCE_ID, DB_ID, Collections.emptyList()); @@ -176,6 +183,7 @@ public void createEncryptedDatabase() throws Exception { client .newDatabaseBuilder(DatabaseId.of(DB_NAME)) .setEncryptionConfig(EncryptionConfigs.customerManagedEncryption(KMS_KEY_NAME)) + .setDialect(Dialect.GOOGLE_STANDARD_SQL) .build(); OperationFuture rawOperationFuture = diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java index d1e8d2e31f5..bd09d131a61 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java @@ -19,6 +19,7 @@ import static com.google.cloud.spanner.DatabaseInfo.State.CREATING; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -31,6 +32,7 @@ import com.google.cloud.spanner.encryption.EncryptionConfigs; import com.google.rpc.Code; import com.google.rpc.Status; +import com.google.spanner.admin.database.v1.DatabaseDialect; import com.google.spanner.admin.database.v1.EncryptionInfo; import java.util.Collections; import java.util.List; @@ -63,6 +65,7 @@ public class DatabaseTest { .setKmsKeyVersion(KMS_KEY_VERSION) .build()); private static final String DEFAULT_LEADER = "default-leader"; + private static final DatabaseDialect DEFAULT_DIALECT = DatabaseDialect.GOOGLE_STANDARD_SQL; @Mock DatabaseAdminClient dbClient; @@ -100,15 +103,42 @@ public void listDatabaseOperations() { } @Test - public void fromProto() { - Database db = createDatabase(); - assertEquals(NAME, db.getId().getName()); - assertEquals(CREATING, db.getState()); - assertEquals(VERSION_RETENTION_PERIOD, db.getVersionRetentionPeriod()); - assertEquals(EARLIEST_VERSION_TIME, db.getEarliestVersionTime()); + public void testFromProto() { + final Database database = createDatabase(); + assertEquals(NAME, database.getId().getName()); + assertEquals(CREATING, database.getState()); + assertEquals(VERSION_RETENTION_PERIOD, database.getVersionRetentionPeriod()); + assertEquals(EARLIEST_VERSION_TIME, database.getEarliestVersionTime()); assertEquals( - EncryptionConfigs.customerManagedEncryption(KMS_KEY_NAME), db.getEncryptionConfig()); - assertEquals(DEFAULT_LEADER, db.getDefaultLeader()); + EncryptionConfigs.customerManagedEncryption(KMS_KEY_NAME), database.getEncryptionConfig()); + assertEquals(DEFAULT_LEADER, database.getDefaultLeader()); + assertEquals(Dialect.GOOGLE_STANDARD_SQL, database.getDialect()); + } + + @Test + public void testUnspecifiedDialectDefaultsToGoogleStandardSqlDialect() { + final Database database = + Database.fromProto( + defaultProtoDatabase() + .toBuilder() + .setDatabaseDialect(DatabaseDialect.DATABASE_DIALECT_UNSPECIFIED) + .build(), + dbClient); + + assertEquals(Dialect.GOOGLE_STANDARD_SQL, database.getDialect()); + } + + @Test + public void testUnrecognizedDialectThrowsException() { + assertThrows( + IllegalArgumentException.class, + () -> + Database.fromProto( + defaultProtoDatabase() + .toBuilder() + .setDatabaseDialect(DatabaseDialect.UNRECOGNIZED) + .build(), + dbClient)); } @Test @@ -137,6 +167,17 @@ public void testBuildWithDefaultLeader() { assertEquals(DEFAULT_LEADER, db.getDefaultLeader()); } + @Test + public void testBuildWithDatabaseDialect() { + final Database database = + dbClient + .newDatabaseBuilder(DatabaseId.of("my-project", "my-instance", "my-database")) + .setDialect(Dialect.GOOGLE_STANDARD_SQL) + .build(); + + assertEquals(Dialect.GOOGLE_STANDARD_SQL, database.getDialect()); + } + @Test public void getIAMPolicy() { Database database = @@ -177,16 +218,19 @@ public void testEqualsAndHashCode() { } private Database createDatabase() { - com.google.spanner.admin.database.v1.Database proto = - com.google.spanner.admin.database.v1.Database.newBuilder() - .setName(NAME) - .setState(com.google.spanner.admin.database.v1.Database.State.CREATING) - .setEarliestVersionTime(EARLIEST_VERSION_TIME.toProto()) - .setVersionRetentionPeriod(VERSION_RETENTION_PERIOD) - .setEncryptionConfig(ENCRYPTION_CONFIG) - .addAllEncryptionInfo(ENCRYPTION_INFOS) - .setDefaultLeader(DEFAULT_LEADER) - .build(); - return Database.fromProto(proto, dbClient); + return Database.fromProto(defaultProtoDatabase(), dbClient); + } + + private com.google.spanner.admin.database.v1.Database defaultProtoDatabase() { + return com.google.spanner.admin.database.v1.Database.newBuilder() + .setName(NAME) + .setState(com.google.spanner.admin.database.v1.Database.State.CREATING) + .setEarliestVersionTime(EARLIEST_VERSION_TIME.toProto()) + .setVersionRetentionPeriod(VERSION_RETENTION_PERIOD) + .setEncryptionConfig(ENCRYPTION_CONFIG) + .addAllEncryptionInfo(ENCRYPTION_INFOS) + .setDefaultLeader(DEFAULT_LEADER) + .setDatabaseDialect(DEFAULT_DIALECT) + .build(); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DialectTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DialectTest.java new file mode 100644 index 00000000000..01c0bc38fc9 --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DialectTest.java @@ -0,0 +1,95 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import com.google.spanner.admin.database.v1.DatabaseDialect; +import org.junit.Test; + +public class DialectTest { + + @Test + public void testCreateDatabaseStatementForGoogleStandardSQLDialect() { + assertEquals( + "CREATE DATABASE `my-database`", + Dialect.GOOGLE_STANDARD_SQL.createDatabaseStatementFor("my-database")); + } + + @Test + public void testCreateDatabaseStatementForPostgreSQLDialect() { + assertEquals( + "CREATE DATABASE \"my-database\"", + Dialect.POSTGRESQL.createDatabaseStatementFor("my-database")); + } + + @Test + public void testGoogleStandardSQLDialectToProto() { + assertEquals(DatabaseDialect.GOOGLE_STANDARD_SQL, Dialect.GOOGLE_STANDARD_SQL.toProto()); + } + + @Test + public void testPostgreSQLToProto() { + assertEquals(DatabaseDialect.POSTGRESQL, Dialect.POSTGRESQL.toProto()); + } + + @Test + public void testFromGoogleStandardSQLDialectProto() { + assertEquals( + Dialect.GOOGLE_STANDARD_SQL, Dialect.fromProto(DatabaseDialect.GOOGLE_STANDARD_SQL)); + } + + @Test + public void testFromUnspecifiedDialectProto() { + assertEquals( + Dialect.GOOGLE_STANDARD_SQL, + Dialect.fromProto(DatabaseDialect.DATABASE_DIALECT_UNSPECIFIED)); + } + + @Test + public void testFromPostgreSQLDialectProto() { + assertEquals(Dialect.POSTGRESQL, Dialect.fromProto(DatabaseDialect.POSTGRESQL)); + } + + @Test + public void testFromUnrecognizedDialectProto() { + assertThrows( + IllegalArgumentException.class, () -> Dialect.fromProto(DatabaseDialect.UNRECOGNIZED)); + } + + @Test + public void testFromNullDialectProto() { + assertThrows( + IllegalArgumentException.class, () -> Dialect.fromProto(DatabaseDialect.UNRECOGNIZED)); + } + + @Test + public void testFromGoogleStandardSQLDialectName() { + assertEquals(Dialect.GOOGLE_STANDARD_SQL, Dialect.fromName("GOOGLE_STANDARD_SQL")); + } + + @Test + public void testFromPostgreSQLDialectName() { + assertEquals(Dialect.POSTGRESQL, Dialect.fromName("POSTGRESQL")); + } + + @Test + public void testFromInvalidDialectName() { + assertThrows(IllegalArgumentException.class, () -> Dialect.fromName("INVALID")); + } +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java index 4ebe92798ec..a307e23db22 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MockSpannerServiceImpl.java @@ -71,6 +71,7 @@ import com.google.spanner.v1.TransactionOptions.ReadWrite; import com.google.spanner.v1.TransactionSelector; import com.google.spanner.v1.Type; +import com.google.spanner.v1.TypeAnnotationCode; import com.google.spanner.v1.TypeCode; import io.grpc.Metadata; import io.grpc.ServerServiceDefinition; @@ -79,6 +80,7 @@ import io.grpc.protobuf.ProtoUtils; import io.grpc.protobuf.lite.ProtoLiteUtils; import io.grpc.stub.StreamObserver; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -1176,84 +1178,99 @@ private Statement buildStatement( String sql, Map paramTypes, com.google.protobuf.Struct params) { Statement.Builder builder = Statement.newBuilder(sql); for (Entry entry : paramTypes.entrySet()) { - com.google.protobuf.Value value = params.getFieldsOrThrow(entry.getKey()); + final String fieldName = entry.getKey(); + final Type fieldType = entry.getValue(); + final Type elementType = fieldType.getArrayElementType(); + com.google.protobuf.Value value = params.getFieldsOrThrow(fieldName); if (value.getKindCase() == KindCase.NULL_VALUE) { - switch (entry.getValue().getCode()) { + switch (fieldType.getCode()) { case ARRAY: - switch (entry.getValue().getArrayElementType().getCode()) { + switch (elementType.getCode()) { case BOOL: - builder.bind(entry.getKey()).toBoolArray((Iterable) null); + builder.bind(fieldName).toBoolArray((Iterable) null); break; case BYTES: - builder.bind(entry.getKey()).toBytesArray(null); + builder.bind(fieldName).toBytesArray(null); break; case DATE: - builder.bind(entry.getKey()).toDateArray(null); + builder.bind(fieldName).toDateArray(null); break; case FLOAT64: - builder.bind(entry.getKey()).toFloat64Array((Iterable) null); + builder.bind(fieldName).toFloat64Array((Iterable) null); break; case INT64: - builder.bind(entry.getKey()).toInt64Array((Iterable) null); + builder.bind(fieldName).toInt64Array((Iterable) null); break; case STRING: - builder.bind(entry.getKey()).toStringArray(null); + builder.bind(fieldName).toStringArray(null); + break; + case NUMERIC: + if (elementType.getTypeAnnotation() == TypeAnnotationCode.PG_NUMERIC) { + builder.bind(fieldName).toPgNumericArray(null); + } else { + builder.bind(fieldName).toNumericArray(null); + } break; case TIMESTAMP: - builder.bind(entry.getKey()).toTimestampArray(null); + builder.bind(fieldName).toTimestampArray(null); break; case JSON: - builder.bind(entry.getKey()).toJsonArray(null); + builder.bind(fieldName).toJsonArray(null); break; case STRUCT: case TYPE_CODE_UNSPECIFIED: case UNRECOGNIZED: default: throw new IllegalArgumentException( - "Unknown or invalid array parameter type: " - + entry.getValue().getArrayElementType().getCode()); + "Unknown or invalid array parameter type: " + elementType.getCode()); } break; case BOOL: - builder.bind(entry.getKey()).to((Boolean) null); + builder.bind(fieldName).to((Boolean) null); break; case BYTES: - builder.bind(entry.getKey()).to((ByteArray) null); + builder.bind(fieldName).to((ByteArray) null); break; case DATE: - builder.bind(entry.getKey()).to((Date) null); + builder.bind(fieldName).to((Date) null); break; case FLOAT64: - builder.bind(entry.getKey()).to((Double) null); + builder.bind(fieldName).to((Double) null); break; case INT64: - builder.bind(entry.getKey()).to((Long) null); + builder.bind(fieldName).to((Long) null); break; case STRING: - builder.bind(entry.getKey()).to((String) null); + builder.bind(fieldName).to((String) null); + break; + case NUMERIC: + if (fieldType.getTypeAnnotation() == TypeAnnotationCode.PG_NUMERIC) { + builder.bind(fieldName).to(Value.pgNumeric(null)); + } else { + builder.bind(fieldName).to((BigDecimal) null); + } break; case STRUCT: - builder.bind(entry.getKey()).to((Struct) null); + builder.bind(fieldName).to((Struct) null); break; case TIMESTAMP: - builder.bind(entry.getKey()).to((com.google.cloud.Timestamp) null); + builder.bind(fieldName).to((com.google.cloud.Timestamp) null); break; case JSON: - builder.bind(entry.getKey()).to(Value.json((String) null)); + builder.bind(fieldName).to(Value.json(null)); break; case TYPE_CODE_UNSPECIFIED: case UNRECOGNIZED: default: - throw new IllegalArgumentException( - "Unknown parameter type: " + entry.getValue().getCode()); + throw new IllegalArgumentException("Unknown parameter type: " + fieldType.getCode()); } } else { - switch (entry.getValue().getCode()) { + switch (fieldType.getCode()) { case ARRAY: - switch (entry.getValue().getArrayElementType().getCode()) { + switch (elementType.getCode()) { case BOOL: builder - .bind(entry.getKey()) + .bind(fieldName) .toBoolArray( (Iterable) GrpcStruct.decodeArrayValue( @@ -1261,7 +1278,7 @@ private Statement buildStatement( break; case BYTES: builder - .bind(entry.getKey()) + .bind(fieldName) .toBytesArray( (Iterable) GrpcStruct.decodeArrayValue( @@ -1269,7 +1286,7 @@ private Statement buildStatement( break; case DATE: builder - .bind(entry.getKey()) + .bind(fieldName) .toDateArray( (Iterable) GrpcStruct.decodeArrayValue( @@ -1277,7 +1294,7 @@ private Statement buildStatement( break; case FLOAT64: builder - .bind(entry.getKey()) + .bind(fieldName) .toFloat64Array( (Iterable) GrpcStruct.decodeArrayValue( @@ -1285,7 +1302,7 @@ private Statement buildStatement( break; case INT64: builder - .bind(entry.getKey()) + .bind(fieldName) .toInt64Array( (Iterable) GrpcStruct.decodeArrayValue( @@ -1293,15 +1310,32 @@ private Statement buildStatement( break; case STRING: builder - .bind(entry.getKey()) + .bind(fieldName) .toStringArray( (Iterable) GrpcStruct.decodeArrayValue( com.google.cloud.spanner.Type.string(), value.getListValue())); break; + case NUMERIC: + if (elementType.getTypeAnnotation() == TypeAnnotationCode.PG_NUMERIC) { + builder + .bind(fieldName) + .toPgNumericArray( + (Iterable) + GrpcStruct.decodeArrayValue( + com.google.cloud.spanner.Type.pgNumeric(), value.getListValue())); + } else { + builder + .bind(fieldName) + .toNumericArray( + (Iterable) + GrpcStruct.decodeArrayValue( + com.google.cloud.spanner.Type.numeric(), value.getListValue())); + } + break; case TIMESTAMP: builder - .bind(entry.getKey()) + .bind(fieldName) .toTimestampArray( (Iterable) GrpcStruct.decodeArrayValue( @@ -1309,7 +1343,7 @@ private Statement buildStatement( break; case JSON: builder - .bind(entry.getKey()) + .bind(fieldName) .toJsonArray( (Iterable) GrpcStruct.decodeArrayValue( @@ -1320,43 +1354,48 @@ private Statement buildStatement( case UNRECOGNIZED: default: throw new IllegalArgumentException( - "Unknown or invalid array parameter type: " - + entry.getValue().getArrayElementType().getCode()); + "Unknown or invalid array parameter type: " + elementType.getCode()); } break; case BOOL: - builder.bind(entry.getKey()).to(value.getBoolValue()); + builder.bind(fieldName).to(value.getBoolValue()); break; case BYTES: - builder.bind(entry.getKey()).to(ByteArray.fromBase64(value.getStringValue())); + builder.bind(fieldName).to(ByteArray.fromBase64(value.getStringValue())); break; case DATE: - builder.bind(entry.getKey()).to(Date.parseDate(value.getStringValue())); + builder.bind(fieldName).to(Date.parseDate(value.getStringValue())); break; case FLOAT64: - builder.bind(entry.getKey()).to(value.getNumberValue()); + builder.bind(fieldName).to(value.getNumberValue()); break; case INT64: - builder.bind(entry.getKey()).to(Long.valueOf(value.getStringValue())); + builder.bind(fieldName).to(Long.valueOf(value.getStringValue())); break; case STRING: - builder.bind(entry.getKey()).to(value.getStringValue()); + builder.bind(fieldName).to(value.getStringValue()); + break; + case NUMERIC: + if (fieldType.getTypeAnnotation() == TypeAnnotationCode.PG_NUMERIC) { + builder.bind(fieldName).to(Value.pgNumeric(value.getStringValue())); + } else { + builder.bind(fieldName).to(new BigDecimal(value.getStringValue())); + } break; case STRUCT: throw new IllegalArgumentException("Struct parameters not (yet) supported"); case TIMESTAMP: builder - .bind(entry.getKey()) + .bind(fieldName) .to(com.google.cloud.Timestamp.parseTimestamp(value.getStringValue())); break; case JSON: - builder.bind(entry.getKey()).to(Value.json(value.getStringValue())); + builder.bind(fieldName).to(Value.json(value.getStringValue())); break; case TYPE_CODE_UNSPECIFIED: case UNRECOGNIZED: default: - throw new IllegalArgumentException( - "Unknown parameter type: " + entry.getValue().getCode()); + throw new IllegalArgumentException("Unknown parameter type: " + fieldType.getCode()); } } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java index 372b2de3034..eb96334b509 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MutationTest.java @@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.testing.EqualsTester; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -512,54 +513,99 @@ private Mutation.WriteBuilder appendAllTypes(Mutation.WriteBuilder builder) { .to(true) .set("boolNull") .to((Boolean) null) + .set("boolValue") + .to(Value.bool(false)) .set("int") .to(42) .set("intNull") .to((Long) null) + .set("intValue") + .to(Value.int64(1L)) .set("float") .to(42.1) .set("floatNull") .to((Double) null) + .set("floatValue") + .to(Value.float64(10D)) .set("string") .to("str") .set("stringNull") .to((String) null) + .set("stringValue") + .to(Value.string("strValue")) + .set("bigDecimal") + .to(BigDecimal.valueOf(123, 2)) + .set("bigDecimalNull") + .to((BigDecimal) null) + .set("bigDecimalValueAsNumeric") + .to(Value.numeric(BigDecimal.TEN)) + .set("pgNumericValue") + .to(Value.pgNumeric("4.2")) + .set("timestamp") + .to(Timestamp.MAX_VALUE) + .set("timestampNull") + .to((Timestamp) null) + .set("timestampValue") + .to(Value.timestamp(Timestamp.MIN_VALUE)) + .set("date") + .to(Date.fromYearMonthDay(2017, 4, 17)) + .set("dateNull") + .to((Date) null) + .set("dateValue") + .to(Value.date(Date.fromYearMonthDay(2021, 1, 2))) .set("boolArr") .toBoolArray(new boolean[] {true, false}) .set("boolArrNull") .toBoolArray((boolean[]) null) + .set("boolArrValue") + .to(Value.boolArray(ImmutableList.of(false, true))) .set("intArr") .toInt64Array(new long[] {1, 2, 3}) .set("intArrNull") .toInt64Array((long[]) null) + .set("intArrValue") + .to(Value.int64Array(ImmutableList.of(1L, 2L))) .set("floatArr") .toFloat64Array(new double[] {1.1, 2.2, 3.3}) .set("floatArrNull") .toFloat64Array((double[]) null) - .set("nullStr") - .to((String) null) - .set("timestamp") - .to(Timestamp.MAX_VALUE) - .set("timestampNull") - .to((Timestamp) null) - .set("date") - .to(Date.fromYearMonthDay(2017, 4, 17)) - .set("dateNull") - .to((Date) null) + .set("floatArrValue") + .to(Value.float64Array(ImmutableList.of(10.1D, 10.2D, 10.3D))) .set("stringArr") .toStringArray(ImmutableList.of("one", "two")) .set("stringArrNull") .toStringArray(null) + .set("stringArrValue") + .to(Value.stringArray(ImmutableList.of("uno", "dos"))) + .set("numericArr") + .toNumericArray(ImmutableList.of(BigDecimal.ONE, BigDecimal.TEN)) + .set("numericArrNull") + .toNumericArray(null) + .set("numericArrValue") + .to(Value.numericArray(ImmutableList.of(BigDecimal.ZERO, BigDecimal.valueOf(234, 2)))) + .set("pgNumericArr") + .toPgNumericArray(ImmutableList.of("1.23", "2.34")) + .set("pgNumericArrNull") + .toPgNumericArray(null) + .set("pgNumericArrValue") + .to(Value.pgNumericArray(ImmutableList.of("10.20", "20.30"))) .set("timestampArr") .toTimestampArray(ImmutableList.of(Timestamp.MAX_VALUE, Timestamp.MAX_VALUE)) .set("timestampArrNull") .toTimestampArray(null) + .set("timestampArrValue") + .to(Value.timestampArray(ImmutableList.of(Timestamp.MIN_VALUE, Timestamp.MAX_VALUE))) .set("dateArr") .toDateArray( ImmutableList.of( Date.fromYearMonthDay(2017, 4, 17), Date.fromYearMonthDay(2017, 4, 18))) .set("dateArrNull") - .toDateArray(null); + .toDateArray(null) + .set("dateArrValue") + .to( + Value.dateArray( + ImmutableList.of( + Date.fromYearMonthDay(2021, 1, 2), Date.fromYearMonthDay(2022, 2, 3)))); } static Matcher matchesProto(String expected) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PgNumericTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PgNumericTest.java new file mode 100644 index 00000000000..77369f5371b --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/PgNumericTest.java @@ -0,0 +1,372 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.NoCredentials; +import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; +import com.google.common.collect.ImmutableMap; +import com.google.protobuf.ListValue; +import com.google.protobuf.NullValue; +import com.google.spanner.v1.CommitRequest; +import com.google.spanner.v1.ExecuteSqlRequest; +import com.google.spanner.v1.ResultSetMetadata; +import com.google.spanner.v1.StructType; +import com.google.spanner.v1.StructType.Field; +import com.google.spanner.v1.TypeAnnotationCode; +import com.google.spanner.v1.TypeCode; +import io.grpc.ManagedChannelBuilder; +import io.grpc.Server; +import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class PgNumericTest { + + private static final String PROJECT = "my-project"; + private static final String INSTANCE = "my-instance"; + private static final String DATABASE = "database"; + private static final ResultSetMetadata RESULT_SET_METADATA = + ResultSetMetadata.newBuilder() + .setRowType( + StructType.newBuilder() + .addFields( + Field.newBuilder() + .setName("PgNumeric") + .setType( + com.google.spanner.v1.Type.newBuilder() + .setCode(TypeCode.NUMERIC) + .setTypeAnnotation(TypeAnnotationCode.PG_NUMERIC) + .build())) + .addFields( + Field.newBuilder() + .setName("PgNumericArray") + .setType( + com.google.spanner.v1.Type.newBuilder() + .setCode(TypeCode.ARRAY) + .setArrayElementType( + com.google.spanner.v1.Type.newBuilder() + .setCode(TypeCode.NUMERIC) + .setTypeAnnotation(TypeAnnotationCode.PG_NUMERIC)) + .build())) + .build()) + .build(); + private static MockSpannerServiceImpl mockSpanner; + private static InetSocketAddress address; + private static Server server; + private Spanner spanner; + private DatabaseClient databaseClient; + + @BeforeClass + public static void beforeClass() throws Exception { + mockSpanner = new MockSpannerServiceImpl(); + mockSpanner.setAbortProbability(0.0D); + + address = new InetSocketAddress("localhost", 0); + server = NettyServerBuilder.forAddress(address).addService(mockSpanner).build().start(); + } + + @AfterClass + public static void afterClass() throws Exception { + server.shutdown(); + server.awaitTermination(); + } + + @Before + public void setUp() throws Exception { + final String endpoint = address.getHostString() + ":" + server.getPort(); + spanner = + SpannerOptions.newBuilder() + .setProjectId(PROJECT) + .setChannelConfigurator(ManagedChannelBuilder::usePlaintext) + .setHost("http://" + endpoint) + .setCredentials(NoCredentials.getInstance()) + .setSessionPoolOption(SessionPoolOptions.newBuilder().setFailOnSessionLeak().build()) + .build() + .getService(); + databaseClient = spanner.getDatabaseClient(DatabaseId.of(PROJECT, INSTANCE, DATABASE)); + } + + @After + public void tearDown() throws Exception { + spanner.close(); + mockSpanner.removeAllExecutionTimes(); + mockSpanner.reset(); + } + + @Test + public void testQueryNoNullsAsStrings() { + final Statement statement = + Statement.of("SELECT PgNumeric, PgNumericArray FROM Table WHERE Id = 0"); + final com.google.spanner.v1.ResultSet result = + com.google.spanner.v1.ResultSet.newBuilder() + .setMetadata(RESULT_SET_METADATA) + .addRows( + ListValue.newBuilder() + .addValues(com.google.protobuf.Value.newBuilder().setStringValue("1.23")) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("2.34")) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("3.45")) + .build())) + .build()) + .build(); + mockSpanner.putStatementResult(StatementResult.query(statement, result)); + + try (ResultSet resultSet = + databaseClient + .singleUse() + .executeQuery( + Statement.of("SELECT PgNumeric, PgNumericArray FROM Table WHERE Id = 0"))) { + resultSet.next(); + + assertEquals("1.23", resultSet.getString("PgNumeric")); + assertEquals("1.23", resultSet.getString(0)); + assertEquals(Arrays.asList("2.34", "3.45"), resultSet.getStringList("PgNumericArray")); + assertEquals(Arrays.asList("2.34", "3.45"), resultSet.getStringList(1)); + } + } + + @Test + public void testQueryNoNullsAsValues() { + final Statement statement = + Statement.of("SELECT PgNumeric, PgNumericArray FROM Table WHERE Id = 0"); + final com.google.spanner.v1.ResultSet result = + com.google.spanner.v1.ResultSet.newBuilder() + .setMetadata(RESULT_SET_METADATA) + .addRows( + ListValue.newBuilder() + .addValues(com.google.protobuf.Value.newBuilder().setStringValue("1.23")) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("2.34")) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("3.45")) + .build())) + .build()) + .build(); + mockSpanner.putStatementResult(StatementResult.query(statement, result)); + + try (ResultSet resultSet = databaseClient.singleUse().executeQuery(statement)) { + resultSet.next(); + + assertEquals(Value.pgNumeric("1.23"), resultSet.getValue("PgNumeric")); + assertEquals(Value.pgNumeric("1.23"), resultSet.getValue(0)); + assertEquals( + Value.pgNumericArray(Arrays.asList("2.34", "3.45")), + resultSet.getValue("PgNumericArray")); + assertEquals(Value.pgNumericArray(Arrays.asList("2.34", "3.45")), resultSet.getValue(1)); + } + } + + @Test + public void testQueryNullElements() { + final Statement statement = + Statement.of("SELECT PgNumeric, PgNumericArray FROM Table WHERE Id = 3"); + final com.google.spanner.v1.ResultSet result = + com.google.spanner.v1.ResultSet.newBuilder() + .setMetadata(RESULT_SET_METADATA) + .addRows( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder().setNullValue(NullValue.NULL_VALUE)) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("1.23")) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE)) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("2.34")) + .addValues( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE)) + .build())) + .build()) + .build(); + mockSpanner.putStatementResult(StatementResult.query(statement, result)); + + try (ResultSet resultSet = databaseClient.singleUse().executeQuery(statement)) { + resultSet.next(); + + assertEquals( + Value.pgNumericArray(Arrays.asList("1.23", null, "2.34", null)), + resultSet.getValue("PgNumericArray")); + assertEquals( + Value.pgNumericArray(Arrays.asList("1.23", null, "2.34", null)), resultSet.getValue(1)); + } + } + + @Test + public void testQueryNaNs() { + final Statement statement = + Statement.of("SELECT PgNumeric, PgNumericArray FROM Table WHERE Id = 2"); + final com.google.spanner.v1.ResultSet result = + com.google.spanner.v1.ResultSet.newBuilder() + .setMetadata(RESULT_SET_METADATA) + .addRows( + ListValue.newBuilder() + .addValues(com.google.protobuf.Value.newBuilder().setStringValue("NaN")) + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("NaN")) + .addValues( + com.google.protobuf.Value.newBuilder() + .setStringValue("NaN")) + .build())) + .build()) + .build(); + mockSpanner.putStatementResult(StatementResult.query(statement, result)); + + try (ResultSet resultSet = databaseClient.singleUse().executeQuery(statement)) { + resultSet.next(); + + assertEquals(Value.pgNumeric("NaN"), resultSet.getValue("PgNumeric")); + assertEquals(Value.pgNumeric("NaN"), resultSet.getValue(0)); + assertEquals( + Value.pgNumericArray(Arrays.asList("NaN", "NaN")), resultSet.getValue("PgNumericArray")); + assertEquals(Value.pgNumericArray(Arrays.asList("NaN", "NaN")), resultSet.getValue(1)); + } + } + + @Test + public void testQueryNulls() { + final Statement statement = + Statement.of("SELECT PgNumeric, PgNumericArray FROM Table WHERE Id = 1"); + final com.google.spanner.v1.ResultSet result = + com.google.spanner.v1.ResultSet.newBuilder() + .setMetadata(RESULT_SET_METADATA) + .addRows( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder().setNullValue(NullValue.NULL_VALUE)) + .addValues( + com.google.protobuf.Value.newBuilder().setNullValue(NullValue.NULL_VALUE)) + .build()) + .build(); + mockSpanner.putStatementResult(StatementResult.query(statement, result)); + + try (ResultSet resultSet = databaseClient.singleUse().executeQuery(statement)) { + resultSet.next(); + + assertTrue(resultSet.isNull("PgNumeric")); + assertTrue(resultSet.isNull(0)); + assertTrue(resultSet.isNull("PgNumericArray")); + assertTrue(resultSet.isNull(1)); + } + } + + @Test + public void testMutation() { + final List mutations = + Collections.singletonList( + Mutation.newInsertBuilder("Table") + .set("PgNumeric") + .to("1.23") + .set("PgNumericNull") + .to((String) null) + .set("PgNumericNaN") + .to("NaN") + .set("PgNumericValue") + .to(Value.pgNumeric("2.34")) + .set("PgNumericArray") + .toStringArray(Arrays.asList("2.34", null, "3.45")) + .set("PgNumericArrayNull") + .toStringArray(null) + .build()); + final List expectedMutations = new ArrayList<>(); + Mutation.toProto(mutations, expectedMutations); + + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.buffer(mutations); + return null; + }); + + final List requests = mockSpanner.getRequestsOfType(CommitRequest.class); + final CommitRequest request = requests.get(0); + assertEquals(1, requests.size()); + assertEquals(expectedMutations, request.getMutationsList()); + } + + @Test + public void testParameterizedStatement() { + final Statement statement = + Statement.newBuilder("SELECT * FROM Table WHERE PgNumeric IN (@col1, @col2, @col3)") + .bind("col1") + .to(Value.pgNumeric("1.23")) + .bind("col2") + .to(Value.pgNumeric("NaN")) + .bind("col3") + .to(Value.pgNumeric(null)) + .build(); + final com.google.spanner.v1.ResultSet result = + com.google.spanner.v1.ResultSet.newBuilder() + .setMetadata(RESULT_SET_METADATA) + .addRows(ListValue.newBuilder().build()) + .build(); + mockSpanner.putStatementResult(StatementResult.query(statement, result)); + + try (ResultSet resultSet = databaseClient.singleUse().executeQuery(statement)) { + resultSet.next(); + + final List requests = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class); + final ExecuteSqlRequest request = requests.get(0); + + assertEquals(1, requests.size()); + assertEquals( + ImmutableMap.of( + "col1", Type.pgNumeric().toProto(), + "col2", Type.pgNumeric().toProto(), + "col3", Type.pgNumeric().toProto()), + request.getParamTypesMap()); + } + } +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java index fc82954ad40..80a542c5305 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java @@ -81,6 +81,7 @@ public void defaultBuilder() { } assertThat(options.getPrefetchChunks()).isEqualTo(4); assertThat(options.getSessionLabels()).isNull(); + assertThat(options.getDialect()).isEqualTo(Dialect.GOOGLE_STANDARD_SQL); } @Test @@ -95,11 +96,13 @@ public void builder() { .setProjectId(projectId) .setPrefetchChunks(2) .setSessionLabels(labels) + .setDialect(Dialect.POSTGRESQL) .build(); assertThat(options.getHost()).isEqualTo(host); assertThat(options.getProjectId()).isEqualTo(projectId); assertThat(options.getPrefetchChunks()).isEqualTo(2); assertThat(options.getSessionLabels()).containsExactlyEntriesIn(labels); + assertThat(options.getDialect()).isEqualTo(Dialect.POSTGRESQL); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StructTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StructTest.java index 75e49cc642f..d357a14f9d0 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StructTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/StructTest.java @@ -22,6 +22,7 @@ import com.google.common.testing.EqualsTester; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -206,6 +207,32 @@ public void equalsAndHashCode() { tester.addEqualityGroup(emptyFieldStruct1, emptyFieldStruct2); tester.testEquals(); + + // PgNumeric + tester.addEqualityGroup( + Struct.newBuilder().set("x").to(Value.pgNumeric("1.23")).build(), + Struct.newBuilder().set("x").to(Value.pgNumeric("1.23")).build()); + tester.addEqualityGroup( + Struct.newBuilder().set("x").to(Value.pgNumeric("NaN")).build(), + Struct.newBuilder().set("x").to(Value.pgNumeric("NaN")).build()); + tester.addEqualityGroup( + Struct.newBuilder().set("x").to(Value.pgNumeric(null)).build(), + Struct.newBuilder().set("x").to(Value.pgNumeric(null)).build()); + tester.addEqualityGroup( + Struct.newBuilder() + .set("x") + .to(Value.pgNumericArray(Arrays.asList(null, "1.23", "NaN"))) + .build(), + Struct.newBuilder() + .set("x") + .to(Value.pgNumericArray(Arrays.asList(null, "1.23", "NaN"))) + .build()); + tester.addEqualityGroup( + Struct.newBuilder().set("x").to(Value.pgNumericArray(Collections.emptyList())).build(), + Struct.newBuilder().set("x").to(Value.pgNumericArray(Collections.emptyList())).build()); + tester.addEqualityGroup( + Struct.newBuilder().set("x").to(Value.pgNumericArray(null)).build(), + Struct.newBuilder().set("x").to(Value.pgNumericArray(null)).build()); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java index afbf273bf89..7dfe9f3a985 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertThrows; import com.google.cloud.spanner.Type.Code; +import com.google.spanner.v1.TypeAnnotationCode; import com.google.spanner.v1.TypeCode; import org.hamcrest.MatcherAssert; import org.junit.Test; @@ -34,12 +35,21 @@ public class TypeTest { private abstract static class ScalarTypeTester { - final Type.Code expectedCode; - final TypeCode expectedProtoCode; + private final Type.Code expectedCode; + private final TypeCode expectedTypeCode; + private final TypeAnnotationCode expectedTypeAnnotationCode; - ScalarTypeTester(Type.Code expectedCode, TypeCode expectedProtoCode) { + ScalarTypeTester(Type.Code expectedCode, TypeCode expectedTypeCode) { + this(expectedCode, expectedTypeCode, TypeAnnotationCode.TYPE_ANNOTATION_CODE_UNSPECIFIED); + } + + ScalarTypeTester( + Type.Code expectedCode, + TypeCode expectedTypeCode, + TypeAnnotationCode expectedTypeAnnotationCode) { this.expectedCode = expectedCode; - this.expectedProtoCode = expectedProtoCode; + this.expectedTypeCode = expectedTypeCode; + this.expectedTypeAnnotationCode = expectedTypeAnnotationCode; } abstract Type newType(); @@ -49,10 +59,17 @@ void test() { assertThat(t.getCode()).isEqualTo(expectedCode); assertThat(newType()).isSameInstanceAs(t); // Interned. // String form is deliberately the same as the corresponding type enum in the public API. - assertThat(t.toString()).isEqualTo(expectedProtoCode.toString()); + if (expectedTypeAnnotationCode != TypeAnnotationCode.TYPE_ANNOTATION_CODE_UNSPECIFIED) { + assertThat(t.toString()) + .isEqualTo( + expectedTypeCode.toString() + "<" + expectedTypeAnnotationCode.toString() + ">"); + } else { + assertThat(t.toString()).isEqualTo(expectedTypeCode.toString()); + } com.google.spanner.v1.Type proto = t.toProto(); - assertThat(proto.getCode()).isEqualTo(expectedProtoCode); + assertThat(proto.getCode()).isEqualTo(expectedTypeCode); + assertThat(proto.getTypeAnnotation()).isEqualTo(expectedTypeAnnotationCode); assertThat(proto.hasArrayElementType()).isFalse(); assertThat(proto.hasStructType()).isFalse(); @@ -105,6 +122,16 @@ Type newType() { }.test(); } + @Test + public void pgNumeric() { + new ScalarTypeTester(Type.Code.PG_NUMERIC, TypeCode.NUMERIC, TypeAnnotationCode.PG_NUMERIC) { + @Override + Type newType() { + return Type.pgNumeric(); + } + }.test(); + } + @Test public void string() { new ScalarTypeTester(Type.Code.STRING, TypeCode.STRING) { @@ -156,14 +183,28 @@ Type newType() { } abstract static class ArrayTypeTester { - final Type.Code expectedElementCode; - final TypeCode expectedElementProtoCode; - final boolean expectInterned; + private final Type.Code expectedElementCode; + private final TypeCode expectedElementTypeCode; + private final TypeAnnotationCode expectedTypeAnnotationCode; + private final boolean expectInterned; + + ArrayTypeTester( + Type.Code expectedElementCode, TypeCode expectedElementTypeCode, boolean expectInterned) { + this( + expectedElementCode, + expectedElementTypeCode, + TypeAnnotationCode.TYPE_ANNOTATION_CODE_UNSPECIFIED, + expectInterned); + } - protected ArrayTypeTester( - Type.Code expectedElementCode, TypeCode expectedElementProtoCode, boolean expectInterned) { + ArrayTypeTester( + Type.Code expectedElementCode, + TypeCode expectedElementTypeCode, + TypeAnnotationCode expectedTypeAnnotationCode, + boolean expectInterned) { this.expectedElementCode = expectedElementCode; - this.expectedElementProtoCode = expectedElementProtoCode; + this.expectedElementTypeCode = expectedElementTypeCode; + this.expectedTypeAnnotationCode = expectedTypeAnnotationCode; this.expectInterned = expectInterned; } @@ -234,6 +275,17 @@ Type newElementType() { }.test(); } + @Test + public void pgNumericArray() { + new ArrayTypeTester( + Type.Code.PG_NUMERIC, TypeCode.NUMERIC, TypeAnnotationCode.PG_NUMERIC, true) { + @Override + Type newElementType() { + return Type.pgNumeric(); + } + }.test(); + } + @Test public void stringArray() { new ArrayTypeTester(Type.Code.STRING, TypeCode.STRING, true) { @@ -296,25 +348,36 @@ Type newElementType() { @Test public void struct() { - Type t = Type.struct(StructField.of("f1", Type.int64()), StructField.of("f2", Type.string())); + Type t = + Type.struct( + StructField.of("f1", Type.int64()), + StructField.of("f2", Type.string()), + StructField.of("f3", Type.pgNumeric())); assertThat(t.getCode()).isEqualTo(Type.Code.STRUCT); // Exercise StructField equality. assertThat(t.getStructFields()) - .containsExactly(StructField.of("f1", Type.int64()), StructField.of("f2", Type.string())) + .containsExactly( + StructField.of("f1", Type.int64()), + StructField.of("f2", Type.string()), + StructField.of("f3", Type.pgNumeric())) .inOrder(); // Exercise StructField getters. assertThat(t.getStructFields().get(0).getName()).isEqualTo("f1"); assertThat(t.getStructFields().get(0).getType()).isEqualTo(Type.int64()); assertThat(t.getStructFields().get(1).getName()).isEqualTo("f2"); assertThat(t.getStructFields().get(1).getType()).isEqualTo(Type.string()); - assertThat(t.toString()).isEqualTo("STRUCT"); + assertThat(t.getStructFields().get(2).getName()).isEqualTo("f3"); + assertThat(t.getStructFields().get(2).getType()).isEqualTo(Type.pgNumeric()); + assertThat(t.toString()).isEqualTo("STRUCT>"); assertThat(t.getFieldIndex("f1")).isEqualTo(0); assertThat(t.getFieldIndex("f2")).isEqualTo(1); + assertThat(t.getFieldIndex("f3")).isEqualTo(2); assertProtoEquals( t.toProto(), "code: STRUCT struct_type { fields { name: 'f1' type { code: INT64 } }" - + " fields { name: 'f2' type { code: STRING } } }"); + + " fields { name: 'f2' type { code: STRING } } " + + " fields { name: 'f3' type { code: NUMERIC, type_annotation: PG_NUMERIC } } }"); } @Test diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java index bc1674e5a0f..122f5582736 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueBinderTest.java @@ -37,6 +37,8 @@ @RunWith(JUnit4.class) public class ValueBinderTest { private static final String JSON_METHOD_NAME = "json"; + private static final String PG_NUMERIC_METHOD_NAME = "pgNumeric"; + public static final String DEFAULT_PG_NUMERIC = "1.23"; private Value lastValue; private int lastReturnValue; @@ -120,6 +122,10 @@ public void reflection() // ValueBinder.to(Value) binderMethod = ValueBinder.class.getMethod("to", Value.class); assertThat(binderMethod.invoke(binder, Value.json(null))).isEqualTo(lastReturnValue); + } else if (method.getName().equalsIgnoreCase(PG_NUMERIC_METHOD_NAME)) { + binderMethod = ValueBinder.class.getMethod("to", Value.class); + assertThat(binderMethod.invoke(binder, Value.pgNumeric(null))) + .isEqualTo(lastReturnValue); } else { assertThat(binderMethod.invoke(binder, (Object) null)).isEqualTo(lastReturnValue); } @@ -136,6 +142,11 @@ public void reflection() binderMethod = ValueBinder.class.getMethod("to", Value.class); assertThat(binderMethod.invoke(binder, Value.json(defaultJson()))) .isEqualTo(lastReturnValue); + } else if (method.getName().equalsIgnoreCase(PG_NUMERIC_METHOD_NAME)) { + defaultObject = DEFAULT_PG_NUMERIC; + binderMethod = ValueBinder.class.getMethod("to", Value.class); + assertThat(binderMethod.invoke(binder, Value.pgNumeric(DEFAULT_PG_NUMERIC))) + .isEqualTo(lastReturnValue); } else { defaultObject = DefaultValues.getDefault(method.getGenericParameterTypes()[0]); assertThat(binderMethod.invoke(binder, defaultObject)).isEqualTo(lastReturnValue); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java index 7c2d7d0a95f..a350fe68469 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/ValueTest.java @@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -174,6 +175,28 @@ public void numeric() { assertThat(v.toString()).isEqualTo("1.23"); } + @Test + public void pgNumeric() { + final Value value = Value.pgNumeric("1234.5678"); + assertEquals(Type.pgNumeric(), value.getType()); + assertFalse("pgNumeric value should not be null", value.isNull()); + assertEquals("1234.5678", value.getString()); + assertEquals(BigDecimal.valueOf(12345678, 4), value.getNumeric()); + assertEquals(1234.5678D, value.getFloat64(), 0.00001); + assertEquals("1234.5678", value.toString()); + } + + @Test + public void pgNumericNaN() { + final Value value = Value.pgNumeric("NaN"); + assertEquals(Type.pgNumeric(), value.getType()); + assertFalse("pgNumeric value should not be null", value.isNull()); + assertEquals("NaN", value.getString()); + assertThrows(NumberFormatException.class, value::getNumeric); + assertEquals(Double.NaN, value.getFloat64(), 0.00001); + assertEquals("NaN", value.toString()); + } + @Test public void testNumericFormats() { // The following is copied from the Numeric proto documentation. @@ -331,6 +354,33 @@ public void numericNull() { assertThat(e.getMessage()).contains("null value"); } + @Test + public void pgNumericNull() { + final Value value = Value.pgNumeric(null); + assertEquals(Type.pgNumeric(), value.getType()); + assertTrue("pgNumeric value should be null", value.isNull()); + assertEquals(NULL_STRING, value.toString()); + + final IllegalStateException e1 = assertThrows(IllegalStateException.class, value::getString); + assertTrue("exception should mention value is null", e1.getMessage().contains("null value")); + final IllegalStateException e2 = assertThrows(IllegalStateException.class, value::getNumeric); + assertTrue("exception should mention value is null", e2.getMessage().contains("null value")); + final IllegalStateException e3 = assertThrows(IllegalStateException.class, value::getFloat64); + assertTrue("exception should mention value is null", e3.getMessage().contains("null value")); + } + + @Test + public void pgNumericInvalid() { + final Value value = Value.pgNumeric("INVALID"); + assertEquals(Type.pgNumeric(), value.getType()); + assertFalse("pgNumeric value should not be null", value.isNull()); + assertEquals("INVALID", value.toString()); + + assertEquals("INVALID", value.getString()); + assertThrows(NumberFormatException.class, value::getNumeric); + assertThrows(NumberFormatException.class, value::getFloat64); + } + @Test public void string() { Value v = Value.string("abc"); @@ -682,6 +732,32 @@ public void numericArray() { assertThat(v.toString()).isEqualTo("[0.1,NULL,0.3]"); } + @Test + public void pgNumericArray() { + final Value value = Value.pgNumericArray(Arrays.asList("1.23", null, "1.24")); + assertFalse("pgNumericArray value should not be null", value.isNull()); + assertEquals(Arrays.asList("1.23", null, "1.24"), value.getStringArray()); + assertEquals( + Arrays.asList(new BigDecimal("1.23"), null, new BigDecimal("1.24")), + value.getNumericArray()); + final List float64Array = value.getFloat64Array(); + assertEquals(1.23D, float64Array.get(0), 0.001); + assertNull(float64Array.get(1)); + assertEquals(1.24D, float64Array.get(2), 0.001); + } + + @Test + public void pgNumericArrayWithNaNs() { + final Value value = Value.pgNumericArray(Arrays.asList("1.23", null, Value.NAN)); + assertFalse("pgNumericArray value should not be null", value.isNull()); + assertEquals(Arrays.asList("1.23", null, "NaN"), value.getStringArray()); + assertThrows(NumberFormatException.class, value::getNumericArray); + final List float64Array = value.getFloat64Array(); + assertEquals(1.23D, float64Array.get(0), 0.001); + assertNull(float64Array.get(1)); + assertEquals(Double.NaN, float64Array.get(2), 0.001); + } + @Test public void numericArrayNull() { Value v = Value.numericArray(null); @@ -692,6 +768,23 @@ public void numericArrayNull() { assertThat(e.getMessage()).contains("null value"); } + @Test + public void pgNumericArrayNull() { + final Value value = Value.pgNumericArray(null); + assertTrue("pgNumericArray value should be null", value.isNull()); + assertEquals(NULL_STRING, value.toString()); + + final IllegalStateException e1 = + assertThrows(IllegalStateException.class, value::getStringArray); + assertTrue("exception should mention value is null", e1.getMessage().contains("null value")); + final IllegalStateException e2 = + assertThrows(IllegalStateException.class, value::getNumericArray); + assertTrue("exception should mention value is null", e2.getMessage().contains("null value")); + final IllegalStateException e3 = + assertThrows(IllegalStateException.class, value::getFloat64Array); + assertTrue("exception should mention value is null", e3.getMessage().contains("null value")); + } + @Test public void numericArrayTryGetInt64Array() { Value value = Value.numericArray(Collections.singletonList(BigDecimal.valueOf(1, 1))); @@ -700,6 +793,16 @@ public void numericArrayTryGetInt64Array() { assertThat(e.getMessage()).contains("Expected: ARRAY actual: ARRAY"); } + @Test + public void pgNumericArrayTryGetInt64Array() { + final Value value = Value.pgNumericArray(Collections.singletonList("1.23")); + + final IllegalStateException e = assertThrows(IllegalStateException.class, value::getInt64Array); + assertTrue( + "exception should mention type expectation", + e.getMessage().contains("Expected: ARRAY actual: ARRAY>")); + } + @Test public void stringArray() { Value v = Value.stringArray(Arrays.asList("a", null, "c")); @@ -1046,6 +1149,13 @@ public void testValueToProto() { com.google.protobuf.Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build(), Value.numeric(null).toProto()); + assertEquals( + com.google.protobuf.Value.newBuilder().setStringValue("1234.5678").build(), + Value.pgNumeric("1234.5678").toProto()); + assertEquals( + com.google.protobuf.Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build(), + Value.pgNumeric(null).toProto()); + assertEquals( com.google.protobuf.Value.newBuilder().setStringValue("2010-02-28").build(), Value.date(Date.fromYearMonthDay(2010, 2, 28)).toProto()); @@ -1150,6 +1260,19 @@ public void testValueToProto() { .build()))) .build(), Value.numericArray(Arrays.asList(new BigDecimal("3.14"), null)).toProto()); + assertEquals( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addAllValues( + Arrays.asList( + com.google.protobuf.Value.newBuilder().setStringValue("1.23").build(), + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build(), + com.google.protobuf.Value.newBuilder().setStringValue("NaN").build()))) + .build(), + Value.pgNumericArray(Arrays.asList("1.23", null, Value.NAN)).toProto()); assertEquals( com.google.protobuf.Value.newBuilder() .setListValue( @@ -1380,6 +1503,45 @@ public void testValueToProto() { Timestamp.parseTimestamp("2012-04-10T15:16:17.123456789Z"), null))) .build()) .toProto()); + // Struct with pgNumeric + assertEquals( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder().setStringValue("1.23").build()) + .build()) + .build(), + Value.struct(Struct.newBuilder().set("x").to(Value.pgNumeric("1.23")).build()).toProto()); + // Struct with pgNumeric Array + assertEquals( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addValues( + com.google.protobuf.Value.newBuilder() + .setListValue( + ListValue.newBuilder() + .addAllValues( + Arrays.asList( + com.google.protobuf.Value.newBuilder() + .setNullValue(NullValue.NULL_VALUE) + .build(), + com.google.protobuf.Value.newBuilder() + .setStringValue("1.23") + .build(), + com.google.protobuf.Value.newBuilder() + .setStringValue("NaN") + .build())) + .build()) + .build()) + .build()) + .build(), + Value.struct( + Struct.newBuilder() + .add(Value.pgNumericArray(Arrays.asList(null, "1.23", "NaN"))) + .build()) + .toProto()); } @Test @@ -1405,6 +1567,11 @@ public void testEqualsHashCode() { tester.addEqualityGroup(Value.numeric(BigDecimal.valueOf(456, 2))); tester.addEqualityGroup(Value.numeric(null)); + tester.addEqualityGroup(Value.pgNumeric("1234.5678"), Value.pgNumeric("1234.5678")); + tester.addEqualityGroup(Value.pgNumeric("NaN"), Value.pgNumeric(Value.NAN)); + tester.addEqualityGroup(Value.pgNumeric("8765.4321")); + tester.addEqualityGroup(Value.pgNumeric(null)); + tester.addEqualityGroup(Value.string("abc"), Value.string("abc")); tester.addEqualityGroup(Value.string("def")); tester.addEqualityGroup(Value.string(null)); @@ -1471,6 +1638,12 @@ public void testEqualsHashCode() { Value.numericArray(Collections.singletonList(BigDecimal.valueOf(3, 1)))); tester.addEqualityGroup(Value.numericArray(null)); + tester.addEqualityGroup( + Value.pgNumericArray(Arrays.asList("1.23", null, Value.NAN)), + Value.pgNumericArray(Arrays.asList("1.23", null, "NaN"))); + tester.addEqualityGroup(Value.pgNumericArray(Collections.singletonList("1.25"))); + tester.addEqualityGroup(Value.pgNumericArray(null), Value.pgNumericArray(null)); + tester.addEqualityGroup( Value.stringArray(Arrays.asList("a", "b")), Value.stringArray(Arrays.asList("a", "b"))); tester.addEqualityGroup(Value.stringArray(Collections.singletonList("c"))); @@ -1529,6 +1702,10 @@ public void serialization() { reserializeAndAssert(Value.numeric(BigDecimal.valueOf(123, 2))); reserializeAndAssert(Value.numeric(null)); + reserializeAndAssert(Value.pgNumeric("1.23")); + reserializeAndAssert(Value.pgNumeric(Value.NAN)); + reserializeAndAssert(Value.pgNumeric(null)); + reserializeAndAssert(Value.string("abc")); reserializeAndAssert(Value.string(null)); @@ -1569,6 +1746,11 @@ public void serialization() { BigDecimal.valueOf(1, 1), BigDecimal.valueOf(2, 1), BigDecimal.valueOf(3, 1)))); reserializeAndAssert(Value.numericArray(null)); + reserializeAndAssert(Value.pgNumericArray(Arrays.asList("1.23", null, Value.NAN))); + reserializeAndAssert( + Value.pgNumericArray(BrokenSerializationList.of("1.23", "1.24", Value.NAN))); + reserializeAndAssert(Value.pgNumericArray(null)); + reserializeAndAssert(Value.timestamp(null)); reserializeAndAssert(Value.timestamp(Value.COMMIT_TIMESTAMP)); reserializeAndAssert(Value.timestamp(Timestamp.now())); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractConnectionImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractConnectionImplTest.java index 9fda9c68bbb..06b2c0cf891 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractConnectionImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractConnectionImplTest.java @@ -33,7 +33,7 @@ import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; -import com.google.cloud.spanner.connection.StatementParser.StatementType; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptTest.java new file mode 100644 index 00000000000..11e27802214 --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner.connection; + +import com.google.cloud.NoCredentials; +import com.google.cloud.spanner.Dialect; +import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnection; +import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnectionProvider; +import com.google.cloud.spanner.connection.SqlScriptVerifier.SpannerGenericConnection; +import com.google.common.base.Preconditions; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public abstract class AbstractSqlScriptTest { + + @Parameter public Dialect dialect; + + @Parameters(name = "dialect = {0}") + public static Object[] data() { + return Dialect.values(); + } + + static class TestConnectionProvider implements GenericConnectionProvider { + final Dialect dialect; + + TestConnectionProvider(Dialect dialect) { + this.dialect = Preconditions.checkNotNull(dialect); + } + + @Override + public GenericConnection getConnection() { + return SpannerGenericConnection.of( + ConnectionImplTest.createConnection( + ConnectionOptions.newBuilder() + .setCredentials(NoCredentials.getInstance()) + .setUri(ConnectionImplTest.URI + ";dialect=" + dialect.name()) + .build())); + } + } +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptVerifier.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptVerifier.java index ccf36449be3..ec40c8c0d0b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptVerifier.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/AbstractSqlScriptVerifier.java @@ -26,6 +26,7 @@ import static org.junit.Assert.fail; import com.google.cloud.Timestamp; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; @@ -136,6 +137,8 @@ public abstract static class GenericConnection implements AutoCloseable { @Override public abstract void close() throws Exception; + + public abstract Dialect getDialect(); } /** @@ -309,7 +312,7 @@ public void verifyStatementsInFile( + " ---- verifying statement:"); System.out.println(sql); } - verifyStatement(variables, connection, sql); + verifyStatement(variables, connection, sql, connection.getDialect()); } connection.close(); } catch (Exception e) { @@ -339,10 +342,14 @@ private List> toBatches(List statements) { } private void verifyStatement( - Map variables, GenericConnection connection, String statement) + Map variables, + GenericConnection connection, + String statement, + Dialect dialect) throws Exception { statement = replaceVariables(variables, statement); - String statementWithoutComments = StatementParser.removeCommentsAndTrim(statement); + String statementWithoutComments = + AbstractStatementParser.getInstance(dialect).removeCommentsAndTrim(statement); Matcher verifyMatcher = VERIFY_PATTERN.matcher(statementWithoutComments); Matcher putMatcher = PUT_PATTERN.matcher(statementWithoutComments); if (verifyMatcher.matches()) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ClientSideStatementsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ClientSideStatementsTest.java index eab14248149..629d8bbc6c7 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ClientSideStatementsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ClientSideStatementsTest.java @@ -16,11 +16,7 @@ package com.google.cloud.spanner.connection; -import com.google.cloud.NoCredentials; import com.google.cloud.spanner.ErrorCode; -import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnection; -import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnectionProvider; -import com.google.cloud.spanner.connection.SqlScriptVerifier.SpannerGenericConnection; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; @@ -31,8 +27,6 @@ import java.util.regex.Pattern; import org.junit.AfterClass; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; /** * Test that runs a pre-generated sql script for {@link ClientSideStatement}s. The sql script can be @@ -43,12 +37,11 @@ *

This class does not need to be implemented for the client libraries of other programming * languages. All test cases are covered by the sql file ClientSideStatementsTest.sql. */ -@RunWith(JUnit4.class) -public class ClientSideStatementsTest { +public class ClientSideStatementsTest extends AbstractSqlScriptTest { @Test public void testExecuteClientSideStatementsScript() throws Exception { - SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider()); + SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider(dialect)); verifier.verifyStatementsInFile("ClientSideStatementsTest.sql", getClass(), true); } @@ -110,18 +103,6 @@ public static void closeLog() { } } - static class TestConnectionProvider implements GenericConnectionProvider { - @Override - public GenericConnection getConnection() { - return SpannerGenericConnection.of( - ConnectionImplTest.createConnection( - ConnectionOptions.newBuilder() - .setCredentials(NoCredentials.getInstance()) - .setUri(ConnectionImplTest.URI) - .build())); - } - } - /** Generates test statements for all {@link ClientSideStatement}s */ private static void generateTestStatements(ClientSideStatementImpl statement) { for (String sql : statement.getExampleStatements()) { @@ -145,7 +126,7 @@ private static void generateTestStatements(ClientSideStatementImpl statement) { log( statement.getExamplePrerequisiteStatements(), withInvalidSuffix(sql), - ErrorCode.INVALID_ARGUMENT); + statement.isQuery() ? ErrorCode.UNIMPLEMENTED : ErrorCode.INVALID_ARGUMENT); final String[] replacements = { "%", "_", "&", "$", "@", "!", "*", "(", ")", "-", "+", "-#", "/", "\\", "?", "-/", "/#", @@ -159,11 +140,11 @@ private static void generateTestStatements(ClientSideStatementImpl statement) { log( statement.getExamplePrerequisiteStatements(), withSuffix(replacement, sql), - ErrorCode.INVALID_ARGUMENT); + statement.isQuery() ? ErrorCode.UNIMPLEMENTED : ErrorCode.INVALID_ARGUMENT); log( statement.getExamplePrerequisiteStatements(), replaceLastSpaceWith(replacement, sql), - ErrorCode.INVALID_ARGUMENT); + statement.isQuery() ? ErrorCode.UNIMPLEMENTED : ErrorCode.INVALID_ARGUMENT); } } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplAutocommitReadOnlyTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplAutocommitReadOnlyTest.java index dd4692a72dd..246dc03bb12 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplAutocommitReadOnlyTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplAutocommitReadOnlyTest.java @@ -20,7 +20,7 @@ import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.TimestampBound.Mode; -import com.google.cloud.spanner.connection.StatementParser.StatementType; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import java.util.concurrent.TimeUnit; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplAutocommitReadWriteTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplAutocommitReadWriteTest.java index 78c21a3233b..48eeb5a96d0 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplAutocommitReadWriteTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplAutocommitReadWriteTest.java @@ -20,7 +20,7 @@ import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.TimestampBound.Mode; -import com.google.cloud.spanner.connection.StatementParser.StatementType; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.java index bfa023c1ddc..61ba525efdb 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.java @@ -16,10 +16,6 @@ package com.google.cloud.spanner.connection; -import com.google.cloud.NoCredentials; -import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnection; -import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnectionProvider; -import com.google.cloud.spanner.connection.SqlScriptVerifier.SpannerGenericConnection; import com.google.common.collect.ImmutableSet; import com.google.common.reflect.ClassPath; import com.google.common.reflect.ClassPath.ClassInfo; @@ -30,8 +26,6 @@ import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; /** * This test executes a SQL script that has been generated from the log of all the subclasses of @@ -45,24 +39,11 @@ * not allowed in AUTOCOMMIT mode, but this has changed to be a no-op). A new test script must also * be generated if additional test cases have been added to {@link AbstractConnectionImplTest}. */ -@RunWith(JUnit4.class) -public class ConnectionImplGeneratedSqlScriptTest { - - static class TestConnectionProvider implements GenericConnectionProvider { - @Override - public GenericConnection getConnection() { - return SpannerGenericConnection.of( - ConnectionImplTest.createConnection( - ConnectionOptions.newBuilder() - .setCredentials(NoCredentials.getInstance()) - .setUri(ConnectionImplTest.URI) - .build())); - } - } +public class ConnectionImplGeneratedSqlScriptTest extends AbstractSqlScriptTest { @Test public void testGeneratedScript() throws Exception { - SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider()); + SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider(dialect)); verifier.verifyStatementsInFile("ConnectionImplGeneratedSqlScriptTest.sql", getClass(), true); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTest.java index f68581ee845..f6afee6da2d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTest.java @@ -45,6 +45,7 @@ import com.google.cloud.spanner.CommitResponse; import com.google.cloud.spanner.CommitStats; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.ForwardingResultSet; import com.google.cloud.spanner.Options; @@ -62,10 +63,10 @@ import com.google.cloud.spanner.TransactionManager; import com.google.cloud.spanner.TransactionRunner; import com.google.cloud.spanner.Type; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.ConnectionImpl.UnitOfWorkType; import com.google.cloud.spanner.connection.ConnectionStatementExecutorImpl.StatementTimeoutGetter; import com.google.cloud.spanner.connection.ReadOnlyStalenessUtil.GetExactStaleness; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; import com.google.cloud.spanner.connection.StatementResult.ResultType; import com.google.cloud.spanner.connection.UnitOfWork.UnitOfWorkState; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; @@ -233,6 +234,11 @@ public static ConnectionImpl createConnection(final ConnectionOptions options) { final SimpleResultSet select1ResultSet = new SimpleResultSet(createSelect1MockResultSet()); final SimpleResultSet select1ResultSetWithStats = new SimpleResultSet(mockResultSetWithStats); + when(singleUseReadOnlyTx.executeQuery( + Mockito.argThat(statement -> statement.getSql().toUpperCase().startsWith("SHOW")))) + .thenThrow( + SpannerExceptionFactory.newSpannerException( + ErrorCode.UNIMPLEMENTED, "SHOW queries are not supported")); when(singleUseReadOnlyTx.executeQuery(Statement.of(SELECT))) .thenAnswer( invocation -> { @@ -271,6 +277,12 @@ public static ConnectionImpl createConnection(final ConnectionOptions options) { } return select1ResultSet; }); + when(txContext.executeQuery( + Mockito.argThat( + statement -> statement.getSql().toUpperCase().startsWith("SHOW")))) + .thenThrow( + SpannerExceptionFactory.newSpannerException( + ErrorCode.UNIMPLEMENTED, "SHOW queries are not supported")); when(txContext.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PLAN)) .thenReturn(select1ResultSetWithStats); when(txContext.analyzeQuery(Statement.of(SELECT), QueryAnalyzeMode.PROFILE)) @@ -1350,6 +1362,7 @@ public void testAddRemoveTransactionRetryListener() { @Test public void testMergeQueryOptions() { ConnectionOptions connectionOptions = mock(ConnectionOptions.class); + when(connectionOptions.getDialect()).thenReturn(Dialect.GOOGLE_STANDARD_SQL); SpannerPool spannerPool = mock(SpannerPool.class); DdlClient ddlClient = mock(DdlClient.class); DatabaseClient dbClient = mock(DatabaseClient.class); @@ -1370,14 +1383,15 @@ UnitOfWork getCurrentUnitOfWorkOrStartNewUnitOfWork() { impl.executeQuery(Statement.of("SELECT FOO FROM BAR")); verify(unitOfWork) .executeQueryAsync( - StatementParser.INSTANCE.parse( - Statement.newBuilder("SELECT FOO FROM BAR") - .withQueryOptions( - QueryOptions.newBuilder() - .setOptimizerVersion("1") - .setOptimizerStatisticsPackage("custom-package-1") - .build()) - .build()), + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse( + Statement.newBuilder("SELECT FOO FROM BAR") + .withQueryOptions( + QueryOptions.newBuilder() + .setOptimizerVersion("1") + .setOptimizerStatisticsPackage("custom-package-1") + .build()) + .build()), AnalyzeMode.NONE); // Execute query with an optimizer version and statistics package set on the connection. @@ -1386,14 +1400,15 @@ UnitOfWork getCurrentUnitOfWorkOrStartNewUnitOfWork() { impl.executeQuery(Statement.of("SELECT FOO FROM BAR")); verify(unitOfWork) .executeQueryAsync( - StatementParser.INSTANCE.parse( - Statement.newBuilder("SELECT FOO FROM BAR") - .withQueryOptions( - QueryOptions.newBuilder() - .setOptimizerVersion("2") - .setOptimizerStatisticsPackage("custom-package-2") - .build()) - .build()), + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse( + Statement.newBuilder("SELECT FOO FROM BAR") + .withQueryOptions( + QueryOptions.newBuilder() + .setOptimizerVersion("2") + .setOptimizerStatisticsPackage("custom-package-2") + .build()) + .build()), AnalyzeMode.NONE); // Execute query with an optimizer version and statistics package set on the connection and @@ -1405,14 +1420,15 @@ UnitOfWork getCurrentUnitOfWorkOrStartNewUnitOfWork() { impl.executeQuery(Statement.of("SELECT FOO FROM BAR"), prefetchOption); verify(unitOfWork) .executeQueryAsync( - StatementParser.INSTANCE.parse( - Statement.newBuilder("SELECT FOO FROM BAR") - .withQueryOptions( - QueryOptions.newBuilder() - .setOptimizerVersion("3") - .setOptimizerStatisticsPackage("custom-package-3") - .build()) - .build()), + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse( + Statement.newBuilder("SELECT FOO FROM BAR") + .withQueryOptions( + QueryOptions.newBuilder() + .setOptimizerVersion("3") + .setOptimizerStatisticsPackage("custom-package-3") + .build()) + .build()), AnalyzeMode.NONE, prefetchOption); @@ -1432,14 +1448,15 @@ UnitOfWork getCurrentUnitOfWorkOrStartNewUnitOfWork() { prefetchOption); verify(unitOfWork) .executeQueryAsync( - StatementParser.INSTANCE.parse( - Statement.newBuilder("SELECT FOO FROM BAR") - .withQueryOptions( - QueryOptions.newBuilder() - .setOptimizerVersion("5") - .setOptimizerStatisticsPackage("custom-package-5") - .build()) - .build()), + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse( + Statement.newBuilder("SELECT FOO FROM BAR") + .withQueryOptions( + QueryOptions.newBuilder() + .setOptimizerVersion("5") + .setOptimizerStatisticsPackage("custom-package-5") + .build()) + .build()), AnalyzeMode.NONE, prefetchOption); } @@ -1449,6 +1466,7 @@ UnitOfWork getCurrentUnitOfWorkOrStartNewUnitOfWork() { public void testStatementTagAlwaysAllowed() { ConnectionOptions connectionOptions = mock(ConnectionOptions.class); when(connectionOptions.isAutocommit()).thenReturn(true); + when(connectionOptions.getDialect()).thenReturn(Dialect.GOOGLE_STANDARD_SQL); SpannerPool spannerPool = mock(SpannerPool.class); DdlClient ddlClient = mock(DdlClient.class); DatabaseClient dbClient = mock(DatabaseClient.class); @@ -1491,6 +1509,7 @@ UnitOfWork getCurrentUnitOfWorkOrStartNewUnitOfWork() { public void testTransactionTagAllowedInTransaction() { ConnectionOptions connectionOptions = mock(ConnectionOptions.class); when(connectionOptions.isAutocommit()).thenReturn(false); + when(connectionOptions.getDialect()).thenReturn(Dialect.GOOGLE_STANDARD_SQL); SpannerPool spannerPool = mock(SpannerPool.class); DdlClient ddlClient = mock(DdlClient.class); DatabaseClient dbClient = mock(DatabaseClient.class); @@ -1531,6 +1550,7 @@ public void testTransactionTagAllowedInTransaction() { public void testTransactionTagNotAllowedWithoutTransaction() { ConnectionOptions connectionOptions = mock(ConnectionOptions.class); when(connectionOptions.isAutocommit()).thenReturn(true); + when(connectionOptions.getDialect()).thenReturn(Dialect.GOOGLE_STANDARD_SQL); SpannerPool spannerPool = mock(SpannerPool.class); DdlClient ddlClient = mock(DdlClient.class); DatabaseClient dbClient = mock(DatabaseClient.class); @@ -1551,6 +1571,7 @@ public void testTransactionTagNotAllowedWithoutTransaction() { public void testTransactionTagNotAllowedAfterTransactionStarted() { ConnectionOptions connectionOptions = mock(ConnectionOptions.class); when(connectionOptions.isAutocommit()).thenReturn(false); + when(connectionOptions.getDialect()).thenReturn(Dialect.GOOGLE_STANDARD_SQL); SpannerPool spannerPool = mock(SpannerPool.class); DdlClient ddlClient = mock(DdlClient.class); DatabaseClient dbClient = mock(DatabaseClient.class); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTransactionalReadOnlyTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTransactionalReadOnlyTest.java index c94b73926d1..d98861d0d1b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTransactionalReadOnlyTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTransactionalReadOnlyTest.java @@ -20,7 +20,7 @@ import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.TimestampBound.Mode; -import com.google.cloud.spanner.connection.StatementParser.StatementType; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import java.util.concurrent.TimeUnit; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTransactionalReadWriteTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTransactionalReadWriteTest.java index 3aa3e9fdd48..1fa01abaf16 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTransactionalReadWriteTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionImplTransactionalReadWriteTest.java @@ -20,7 +20,7 @@ import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.TimestampBound.Mode; -import com.google.cloud.spanner.connection.StatementParser.StatementType; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import java.util.concurrent.TimeUnit; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java index 1f9bad7b6c2..e8758c36d03 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java @@ -22,9 +22,12 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.rpc.TransportChannelProvider; import com.google.auth.oauth2.GoogleCredentials; import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.cloud.NoCredentials; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerOptions; @@ -573,4 +576,77 @@ public void testSetCredentialsAndEncodedCredentials() throws Exception { .contains( "Cannot specify both a credentials URL and encoded credentials. Only set one of the properties."); } + + @Test + public void testSetDialect() { + ConnectionOptions options = + ConnectionOptions.newBuilder() + .setCredentials(NoCredentials.getInstance()) + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database") + .build(); + assertThat(options.getDialect()).isEqualTo(Dialect.GOOGLE_STANDARD_SQL); + + ConnectionOptions optionsSpanner = + ConnectionOptions.newBuilder() + .setCredentials(NoCredentials.getInstance()) + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?dialect=GOOGLE_STANDARD_SQL") + .build(); + assertThat(optionsSpanner.getDialect()).isEqualTo(Dialect.GOOGLE_STANDARD_SQL); + + ConnectionOptions optionsPostgreSQL = + ConnectionOptions.newBuilder() + .setCredentials(NoCredentials.getInstance()) + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?dialect=POSTGRESQL") + .build(); + assertThat(optionsPostgreSQL.getDialect()).isEqualTo(Dialect.POSTGRESQL); + + ConnectionOptions optionsSpannerLC = + ConnectionOptions.newBuilder() + .setCredentials(NoCredentials.getInstance()) + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?dialect=google_standard_sql") + .build(); + assertThat(optionsSpannerLC.getDialect()).isEqualTo(Dialect.GOOGLE_STANDARD_SQL); + + ConnectionOptions optionsPostgreSQLLC = + ConnectionOptions.newBuilder() + .setCredentials(NoCredentials.getInstance()) + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?dialect=postgresql") + .build(); + assertThat(optionsPostgreSQLLC.getDialect()).isEqualTo(Dialect.POSTGRESQL); + + try { + ConnectionOptions.newBuilder() + .setCredentials(NoCredentials.getInstance()) + .setUri( + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database?dialect=POSTGRES") + .build(); + fail("missing expected exception"); + } catch (SpannerException e) { + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(e.getMessage()) + .contains("Dialect must be one of [GOOGLE_STANDARD_SQL, POSTGRESQL]"); + } + } + + @Test + public void testExternalChannelProvider() { + String baseUri = + "cloudspanner:/projects/test-project-123/instances/test-instance/databases/test-database"; + + ConnectionOptions options = + ConnectionOptions.newBuilder() + .setUri( + baseUri + + "?channelProvider=com.google.cloud.spanner.connection.TestChannelProvider") + .setCredentials(NoCredentials.getInstance()) + .build(); + + TransportChannelProvider provider = options.getChannelProvider(); + assertTrue(provider instanceof InstantiatingGrpcChannelProvider); + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementWithNoParametersTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementWithNoParametersTest.java index 84c6b8c8ced..2f2b538d073 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementWithNoParametersTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementWithNoParametersTest.java @@ -22,14 +22,33 @@ import static org.mockito.Mockito.when; import com.google.cloud.Timestamp; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import java.util.concurrent.TimeUnit; +import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; +@RunWith(Parameterized.class) public class ConnectionStatementWithNoParametersTest { - private final StatementParser parser = StatementParser.INSTANCE; + @Parameter public Dialect dialect; + + @Parameters(name = "dialect = {0}") + public static Object[] data() { + return Dialect.values(); + } + + private AbstractStatementParser parser; + + @Before + public void setup() { + parser = AbstractStatementParser.getInstance(dialect); + } @Test public void testExecuteGetAutocommit() { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementWithOneParameterTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementWithOneParameterTest.java index fee70f05eaa..645d2f3b566 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementWithOneParameterTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionStatementWithOneParameterTest.java @@ -23,15 +23,34 @@ import static org.mockito.Mockito.when; import com.google.cloud.Timestamp; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.protobuf.Duration; import java.util.concurrent.TimeUnit; +import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; +@RunWith(Parameterized.class) public class ConnectionStatementWithOneParameterTest { - private final StatementParser parser = StatementParser.INSTANCE; + @Parameter public Dialect dialect; + + @Parameters(name = "dialect = {0}") + public static Object[] data() { + return Dialect.values(); + } + + private AbstractStatementParser parser; + + @Before + public void setup() { + parser = AbstractStatementParser.getInstance(dialect); + } @Test public void testExecuteSetAutocommit() { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java index 0d310df6905..23792572d79 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java @@ -36,6 +36,7 @@ import com.google.api.core.ApiFutures; import com.google.api.gax.longrunning.OperationFuture; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.ReadContext; @@ -44,9 +45,9 @@ import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.cloud.spanner.connection.Connection.InternalMetadataQuery; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; -import com.google.cloud.spanner.connection.StatementParser.StatementType; import com.google.cloud.spanner.connection.UnitOfWork.UnitOfWorkState; import com.google.protobuf.Timestamp; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; @@ -393,8 +394,12 @@ public void testUpdateCount() throws InterruptedException, ExecutionException { .setDdlClient(client) .setDatabaseClient(mock(DatabaseClient.class)) .build(); - batch.executeDdlAsync(StatementParser.INSTANCE.parse(Statement.of("CREATE TABLE FOO"))); - batch.executeDdlAsync(StatementParser.INSTANCE.parse(Statement.of("CREATE TABLE BAR"))); + batch.executeDdlAsync( + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("CREATE TABLE FOO"))); + batch.executeDdlAsync( + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("CREATE TABLE BAR"))); long[] updateCounts = get(batch.runBatchAsync()); assertThat(updateCounts.length, is(equalTo(2))); assertThat(updateCounts[0], is(equalTo(1L))); @@ -425,9 +430,12 @@ public void testFailedUpdateCount() throws InterruptedException, ExecutionExcept .setDdlClient(client) .setDatabaseClient(mock(DatabaseClient.class)) .build(); - batch.executeDdlAsync(StatementParser.INSTANCE.parse(Statement.of("CREATE TABLE FOO"))); batch.executeDdlAsync( - StatementParser.INSTANCE.parse(Statement.of("CREATE TABLE INVALID_TABLE"))); + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("CREATE TABLE FOO"))); + batch.executeDdlAsync( + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("CREATE TABLE INVALID_TABLE"))); try { get(batch.runBatchAsync()); fail("missing expected exception"); @@ -462,9 +470,12 @@ public void testFailedAfterFirstStatement() throws InterruptedException, Executi .setDdlClient(client) .setDatabaseClient(mock(DatabaseClient.class)) .build(); - batch.executeDdlAsync(StatementParser.INSTANCE.parse(Statement.of("CREATE TABLE FOO"))); batch.executeDdlAsync( - StatementParser.INSTANCE.parse(Statement.of("CREATE TABLE INVALID_TABLE"))); + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("CREATE TABLE FOO"))); + batch.executeDdlAsync( + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("CREATE TABLE INVALID_TABLE"))); try { get(batch.runBatchAsync()); fail("missing expected exception"); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DmlBatchTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DmlBatchTest.java index 10a8d5d46c4..f92b5bf1a92 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DmlBatchTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DmlBatchTest.java @@ -27,12 +27,13 @@ import static org.mockito.Mockito.when; import com.google.api.core.ApiFutures; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Statement; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; -import com.google.cloud.spanner.connection.StatementParser.StatementType; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.cloud.spanner.connection.UnitOfWork.UnitOfWorkState; import java.util.Arrays; import java.util.Collections; @@ -44,9 +45,11 @@ public class DmlBatchTest { private final ParsedStatement statement1 = - StatementParser.INSTANCE.parse(Statement.of("UPDATE FOO SET BAR=1 WHERE BAZ=2")); + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("UPDATE FOO SET BAR=1 WHERE BAZ=2")); private final ParsedStatement statement2 = - StatementParser.INSTANCE.parse(Statement.of("UPDATE FOO SET BAR=2 WHERE BAZ=3")); + AbstractStatementParser.getInstance(Dialect.GOOGLE_STANDARD_SQL) + .parse(Statement.of("UPDATE FOO SET BAR=2 WHERE BAZ=3")); private DmlBatch createSubject() { UnitOfWork transaction = mock(UnitOfWork.class); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ITAbstractSpannerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ITAbstractSpannerTest.java index 0a16b102097..a36b12b2fe9 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ITAbstractSpannerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ITAbstractSpannerTest.java @@ -29,8 +29,8 @@ import com.google.cloud.spanner.TransactionManager.TransactionState; import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnection; import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnectionProvider; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.SqlScriptVerifier.SpannerGenericConnection; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; import com.google.common.base.Preconditions; import com.google.common.base.Stopwatch; import com.google.common.base.Strings; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadOnlyTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadOnlyTransactionTest.java index 28d8b986029..027d85bc8d2 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadOnlyTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadOnlyTransactionTest.java @@ -44,8 +44,8 @@ import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.TimestampBound; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; -import com.google.cloud.spanner.connection.StatementParser.StatementType; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.cloud.spanner.connection.UnitOfWork.UnitOfWorkState; import com.google.spanner.v1.ResultSetStats; import java.util.Arrays; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java index a4e2397db83..aae85bcec62 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ReadWriteTransactionTest.java @@ -50,8 +50,8 @@ import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.StructField; import com.google.cloud.spanner.Value; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; -import com.google.cloud.spanner.connection.StatementParser.StatementType; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.rpc.RetryInfo; import com.google.spanner.v1.ResultSetStats; import io.grpc.Metadata; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetReadOnlyStalenessSqlScriptTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetReadOnlyStalenessSqlScriptTest.java index 25aad948fee..ce3f5b99d48 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetReadOnlyStalenessSqlScriptTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetReadOnlyStalenessSqlScriptTest.java @@ -16,32 +16,13 @@ package com.google.cloud.spanner.connection; -import com.google.cloud.NoCredentials; -import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnection; -import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnectionProvider; -import com.google.cloud.spanner.connection.SqlScriptVerifier.SpannerGenericConnection; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -@RunWith(JUnit4.class) -public class SetReadOnlyStalenessSqlScriptTest { - - static class TestConnectionProvider implements GenericConnectionProvider { - @Override - public GenericConnection getConnection() { - return SpannerGenericConnection.of( - ConnectionImplTest.createConnection( - ConnectionOptions.newBuilder() - .setCredentials(NoCredentials.getInstance()) - .setUri(ConnectionImplTest.URI) - .build())); - } - } +public class SetReadOnlyStalenessSqlScriptTest extends AbstractSqlScriptTest { @Test public void testSetReadOnlyStalenessScript() throws Exception { - SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider()); + SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider(dialect)); verifier.verifyStatementsInFile("SetReadOnlyStalenessTest.sql", getClass(), true); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetStatementTimeoutSqlScriptTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetStatementTimeoutSqlScriptTest.java index c47fde41c17..5ec209dac3f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetStatementTimeoutSqlScriptTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SetStatementTimeoutSqlScriptTest.java @@ -16,32 +16,13 @@ package com.google.cloud.spanner.connection; -import com.google.cloud.NoCredentials; -import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnection; -import com.google.cloud.spanner.connection.AbstractSqlScriptVerifier.GenericConnectionProvider; -import com.google.cloud.spanner.connection.SqlScriptVerifier.SpannerGenericConnection; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -@RunWith(JUnit4.class) -public class SetStatementTimeoutSqlScriptTest { - - static class TestConnectionProvider implements GenericConnectionProvider { - @Override - public GenericConnection getConnection() { - return SpannerGenericConnection.of( - ConnectionImplTest.createConnection( - ConnectionOptions.newBuilder() - .setUri(ConnectionImplTest.URI) - .setCredentials(NoCredentials.getInstance()) - .build())); - } - } +public class SetStatementTimeoutSqlScriptTest extends AbstractSqlScriptTest { @Test public void testSetStatementTimeoutScript() throws Exception { - SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider()); + SqlScriptVerifier verifier = new SqlScriptVerifier(new TestConnectionProvider(dialect)); verifier.verifyStatementsInFile("SetStatementTimeoutTest.sql", getClass(), true); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java index c927718d229..26a3952be28 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java @@ -50,9 +50,9 @@ import com.google.cloud.spanner.TransactionContext; import com.google.cloud.spanner.TransactionManager; import com.google.cloud.spanner.TransactionRunner; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.cloud.spanner.connection.StatementExecutor.StatementTimeout; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; -import com.google.cloud.spanner.connection.StatementParser.StatementType; import com.google.common.base.Preconditions; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import com.google.spanner.v1.ResultSetStats; diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SqlScriptVerifier.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SqlScriptVerifier.java index 2c3eae6623d..d9de876ceda 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SqlScriptVerifier.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SqlScriptVerifier.java @@ -21,6 +21,7 @@ import static org.hamcrest.CoreMatchers.startsWith; import static org.hamcrest.MatcherAssert.assertThat; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.SpannerException; @@ -156,6 +157,11 @@ public void close() { this.connection.close(); } } + + @Override + public Dialect getDialect() { + return connection.getDialect(); + } } public SqlScriptVerifier() { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java index 47f79979135..d2176b53a2e 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java @@ -16,17 +16,24 @@ package com.google.cloud.spanner.connection; +import static com.google.common.truth.Truth.assertThat; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import com.google.cloud.spanner.Dialect; +import com.google.cloud.spanner.ErrorCode; +import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; +import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; import com.google.cloud.spanner.connection.ClientSideStatementImpl.CompileException; -import com.google.cloud.spanner.connection.StatementParser.ParsedStatement; +import com.google.common.collect.ImmutableMap; +import com.google.common.truth.Truth; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; @@ -35,8 +42,15 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.junit.Assume; +import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; +@RunWith(Parameterized.class) public class StatementParserTest { public static final String COPYRIGHT_PATTERN = "\\/\\*\n" @@ -54,12 +68,32 @@ public class StatementParserTest { + " \\* See the License for the specific language governing permissions and\n" + " \\* limitations under the License.\n" + " \\*\\/\n"; - private final StatementParser parser = StatementParser.INSTANCE; private static final Pattern EXPECT_PATTERN = Pattern.compile("(?is)\\s*(?:@EXPECT)\\s+'(.*)'"); + @Parameter public Dialect dialect; + + @Parameters(name = "dialect = {0}") + public static Object[] data() { + return Dialect.values(); + } + + private AbstractStatementParser parser; + + @Before + public void setupParser() { + parser = AbstractStatementParser.getInstance(dialect); + } + + private static final ImmutableMap COMMENTS_SCRIPTS = + ImmutableMap.of( + Dialect.GOOGLE_STANDARD_SQL, + "CommentsTest.sql", + Dialect.POSTGRESQL, + "PostgreSQLCommentsTest.sql"); + @Test - public void testRemoveComments() { - List statements = readStatementsFromFile("CommentsTest.sql"); + public void testRemoveCommentsInScript() { + List statements = readStatementsFromFile(COMMENTS_SCRIPTS.get(dialect)); String currentlyExpected = ""; for (String statement : statements) { String sql = statement.trim(); @@ -71,30 +105,78 @@ public void testRemoveComments() { throw new IllegalArgumentException("Unknown @EXPECT statement: " + sql); } } else { - assertThat( - StatementParser.removeCommentsAndTrim(statement), is(equalTo(currentlyExpected))); + assertThat(parser.removeCommentsAndTrim(statement)).isEqualTo(currentlyExpected); } } + } + + @Test + public void testRemoveComments() { + assertThat(parser.removeCommentsAndTrim("")).isEqualTo(""); + assertThat(parser.removeCommentsAndTrim("SELECT * FROM FOO")).isEqualTo("SELECT * FROM FOO"); + assertThat(parser.removeCommentsAndTrim("-- This is a one line comment\nSELECT * FROM FOO")) + .isEqualTo("SELECT * FROM FOO"); + assertThat( + parser.removeCommentsAndTrim( + "/* This is a simple multi line comment */\nSELECT * FROM FOO")) + .isEqualTo("SELECT * FROM FOO"); + assertThat( + parser.removeCommentsAndTrim("/* This is a \nmulti line comment */\nSELECT * FROM FOO")) + .isEqualTo("SELECT * FROM FOO"); + assertThat( + parser.removeCommentsAndTrim( + "/* This\nis\na\nmulti\nline\ncomment */\nSELECT * FROM FOO")) + .isEqualTo("SELECT * FROM FOO"); + } + + @Test + public void testGoogleStandardSQLRemoveCommentsGsql() { + Assume.assumeTrue(dialect == Dialect.GOOGLE_STANDARD_SQL); - assertThat(StatementParser.removeCommentsAndTrim(""), is(equalTo(""))); + assertThat(parser.removeCommentsAndTrim("/*GSQL*/")).isEqualTo(""); + assertThat(parser.removeCommentsAndTrim("/*GSQL*/SELECT * FROM FOO")) + .isEqualTo("SELECT * FROM FOO"); + assertThat( + parser.removeCommentsAndTrim( + "/*GSQL*/-- This is a one line comment\nSELECT * FROM FOO")) + .isEqualTo("SELECT * FROM FOO"); assertThat( - StatementParser.removeCommentsAndTrim("SELECT * FROM FOO"), - is(equalTo("SELECT * FROM FOO"))); + parser.removeCommentsAndTrim( + "/*GSQL*//* This is a simple multi line comment */\nSELECT * FROM FOO")) + .isEqualTo("SELECT * FROM FOO"); assertThat( - StatementParser.removeCommentsAndTrim("-- This is a one line comment\nSELECT * FROM FOO"), - is(equalTo("SELECT * FROM FOO"))); + parser.removeCommentsAndTrim( + "/*GSQL*//* This is a \nmulti line comment */\nSELECT * FROM FOO")) + .isEqualTo("SELECT * FROM FOO"); assertThat( - StatementParser.removeCommentsAndTrim( - "/* This is a simple multi line comment */\nSELECT * FROM FOO"), - is(equalTo("SELECT * FROM FOO"))); + parser.removeCommentsAndTrim( + "/*GSQL*//* This\nis\na\nmulti\nline\ncomment */\nSELECT * FROM FOO")) + .isEqualTo("SELECT * FROM FOO"); + } + + @Test + public void testPostgreSQLDialectRemoveCommentsGsql() { + Assume.assumeTrue(dialect == Dialect.POSTGRESQL); + + assertThat(parser.removeCommentsAndTrim("/*GSQL*/")).isEqualTo("/*GSQL*/"); + assertThat(parser.removeCommentsAndTrim("/*GSQL*/SELECT * FROM FOO")) + .isEqualTo("/*GSQL*/SELECT * FROM FOO"); assertThat( - StatementParser.removeCommentsAndTrim( - "/* This is a \nmulti line comment */\nSELECT * FROM FOO"), - is(equalTo("SELECT * FROM FOO"))); + parser.removeCommentsAndTrim( + "/*GSQL*/-- This is a one line comment\nSELECT * FROM FOO")) + .isEqualTo("/*GSQL*/SELECT * FROM FOO"); assertThat( - StatementParser.removeCommentsAndTrim( - "/* This\nis\na\nmulti\nline\ncomment */\nSELECT * FROM FOO"), - is(equalTo("SELECT * FROM FOO"))); + parser.removeCommentsAndTrim( + "/*GSQL*//* This is a simple multi line comment */\nSELECT * FROM FOO")) + .isEqualTo("/*GSQL*/SELECT * FROM FOO"); + assertThat( + parser.removeCommentsAndTrim( + "/*GSQL*//* This is a \nmulti line comment */\nSELECT * FROM FOO")) + .isEqualTo("/*GSQL*/SELECT * FROM FOO"); + assertThat( + parser.removeCommentsAndTrim( + "/*GSQL*//* This\nis\na\nmulti\nline\ncomment */\nSELECT * FROM FOO")) + .isEqualTo("/*GSQL*/SELECT * FROM FOO"); } @Test @@ -126,7 +208,7 @@ public void testStatementWithCommentContainingSlash() { + " UPDATE SET FirstName = v.column2,\n" + " LastName = v.column3"; ParsedStatement statement = parser.parse(Statement.of(sql)); - assertThat(statement.getSqlWithoutComments(), is(equalTo(sqlWithoutComments))); + assertThat(statement.getSqlWithoutComments()).isEqualTo(sqlWithoutComments); } @Test @@ -159,92 +241,215 @@ public void testStatementWithCommentContainingSlashAndNoAsteriskOnNewLine() { + " UPDATE SET FirstName = v.column2,\n" + " LastName = v.column3"; ParsedStatement statement = parser.parse(Statement.of(sql)); - assertThat(statement.getSqlWithoutComments(), is(equalTo(sqlWithoutComments))); + assertThat(statement.getSqlWithoutComments()).isEqualTo(sqlWithoutComments); } @Test - public void testStatementWithHashTagSingleLineComment() { + public void testPostgresSQLDialectDollarQuoted() { + Assume.assumeTrue(dialect == Dialect.POSTGRESQL); + + assertThat(parser.removeCommentsAndTrim("$$foo$$")).isEqualTo("$$foo$$"); + assertThat(parser.removeCommentsAndTrim("$$--foo$$")).isEqualTo("$$--foo$$"); + assertThat(parser.removeCommentsAndTrim("$$\nline 1\n--line2$$")) + .isEqualTo("$$\nline 1\n--line2$$"); + assertThat(parser.removeCommentsAndTrim("$bar$--foo$bar$")).isEqualTo("$bar$--foo$bar$"); assertThat( - parser - .parse(Statement.of("# this is a comment\nselect * from foo")) - .getSqlWithoutComments(), - is(equalTo("select * from foo"))); + parser.removeCommentsAndTrim( + "$bar$\nThis is a valid string\n -- That could contain special characters$bar$")) + .isEqualTo("$bar$\nThis is a valid string\n -- That could contain special characters$bar$"); + + assertThat(parser.removeCommentsAndTrim("SELECT FOO$BAR FROM SOME_TABLE")) + .isEqualTo("SELECT FOO$BAR FROM SOME_TABLE"); + assertThat(parser.removeCommentsAndTrim("SELECT FOO$BAR -- This is a comment\nFROM SOME_TABLE")) + .isEqualTo("SELECT FOO$BAR \nFROM SOME_TABLE"); assertThat( - parser.parse(Statement.of("select * from foo\n#this is a comment")).getSqlWithoutComments(), - is(equalTo("select * from foo"))); + parser.removeCommentsAndTrim("SELECT FOO, $BAR -- This is a comment\nFROM SOME_TABLE")) + .isEqualTo("SELECT FOO, $BAR \nFROM SOME_TABLE"); + } + + @Test + public void testPostgreSQLDialectSupportsEmbeddedComments() { + Assume.assumeTrue(dialect == Dialect.POSTGRESQL); + + final String sql = + "/* This is a comment /* This is an embedded comment */ This is after the embedded comment */ SELECT 1"; + assertEquals("SELECT 1", parser.removeCommentsAndTrim(sql)); + } + + @Test + public void testGoogleStandardSQLDialectDoesNotSupportEmbeddedComments() { + Assume.assumeTrue(dialect == Dialect.GOOGLE_STANDARD_SQL); + + final String sql = + "/* This is a comment /* This is an embedded comment */ This is after the embedded comment */ SELECT 1"; + assertEquals( + "This is after the embedded comment */ SELECT 1", parser.removeCommentsAndTrim(sql)); + } + + @Test + public void testPostgreSQLDialectUnterminatedComment() { + Assume.assumeTrue(dialect == Dialect.POSTGRESQL); + + final String sql = + "/* This is a comment /* This is still a comment */ this is unterminated SELECT 1"; + try { + // Cloud Spanner would see this as a valid comment, while PostgreSQL + // requires 'embedded' comments to be properly terminated. + parser.removeCommentsAndTrim(sql); + fail("missing expected exception"); + } catch (SpannerException e) { + assertEquals(ErrorCode.INVALID_ARGUMENT, e.getErrorCode()); + assertTrue( + "Message should contain 'unterminated block comment'", + e.getMessage().contains("unterminated block comment")); + } + } + + @Test + public void testGoogleStandardSqlDialectDialectUnterminatedComment() { + Assume.assumeTrue(dialect == Dialect.GOOGLE_STANDARD_SQL); + + final String sql = + "/* This is a comment /* This is still a comment */ this is unterminated SELECT 1"; + assertEquals("this is unterminated SELECT 1", parser.removeCommentsAndTrim(sql)); + } + + @Test + public void testShowStatements() { + AbstractStatementParser parser = AbstractStatementParser.getInstance(dialect); + + assertThat(parser.parse(Statement.of("show variable autocommit bar")).getType()) + .isEqualTo(StatementType.QUERY); + assertThat(parser.parse(Statement.of("show variable autocommit")).getType()) + .isEqualTo(StatementType.CLIENT_SIDE); + assertThat(parser.parse(Statement.of("show autocommit")).getType()) + .isEqualTo(StatementType.QUERY); + + assertThat(parser.parse(Statement.of("show variable retry_aborts_internally")).getType()) + .isEqualTo(StatementType.CLIENT_SIDE); + assertThat(parser.parse(Statement.of("show variable retry_aborts_internally bar")).getType()) + .isEqualTo(StatementType.QUERY); + } + + @Test + public void testGoogleStandardSQLDialectStatementWithHashTagSingleLineComment() { + Assume.assumeTrue(dialect == Dialect.GOOGLE_STANDARD_SQL); + + // Supports # based comments assertThat( - parser - .parse(Statement.of("select *\nfrom foo # this is a comment\nwhere bar=1")) - .getSqlWithoutComments(), - is(equalTo("select *\nfrom foo \nwhere bar=1"))); + parser + .parse(Statement.of("# this is a comment\nselect * from foo")) + .getSqlWithoutComments()) + .isEqualTo("select * from foo"); + assertThat( + parser + .parse(Statement.of("select * from foo\n#this is a comment")) + .getSqlWithoutComments()) + .isEqualTo("select * from foo"); + assertThat( + parser + .parse(Statement.of("select *\nfrom foo # this is a comment\nwhere bar=1")) + .getSqlWithoutComments()) + .isEqualTo("select *\nfrom foo \nwhere bar=1"); + } + + @Test + public void testPostgreSQLDialectStatementWithHashTagSingleLineComment() { + Assume.assumeTrue(dialect == Dialect.POSTGRESQL); + + // Does not support # based comments + assertThat( + parser + .parse(Statement.of("# this is a comment\nselect * from foo")) + .getSqlWithoutComments()) + .isEqualTo("# this is a comment\nselect * from foo"); + assertThat( + parser + .parse(Statement.of("select * from foo\n#this is a comment")) + .getSqlWithoutComments()) + .isEqualTo("select * from foo\n#this is a comment"); + assertThat( + parser + .parse(Statement.of("select *\nfrom foo # this is a comment\nwhere bar=1")) + .getSqlWithoutComments()) + .isEqualTo("select *\nfrom foo # this is a comment\nwhere bar=1"); } @Test public void testIsDdlStatement() { - assertFalse(parser.isDdlStatement("")); - assertFalse(parser.isDdlStatement("random text")); - assertFalse(parser.isDdlStatement("CREATETABLE")); - assertFalse(parser.isDdlStatement("CCREATE TABLE")); - assertFalse(parser.isDdlStatement("SELECT 1")); - assertFalse(parser.isDdlStatement("SELECT FOO FROM BAR")); - assertFalse(parser.isDdlStatement("INSERT INTO FOO (ID, NAME) VALUES (1, 'NAME')")); - assertFalse(parser.isDdlStatement("UPDATE FOO SET NAME='NAME' WHERE ID=1")); - assertFalse(parser.isDdlStatement("DELETE FROM FOO")); + assertThat(parser.isDdlStatement("")).isFalse(); + assertThat(parser.isDdlStatement("random text")).isFalse(); + assertThat(parser.isDdlStatement("CREATETABLE")).isFalse(); + assertThat(parser.isDdlStatement("CCREATE TABLE")).isFalse(); + assertThat(parser.isDdlStatement("SELECT 1")).isFalse(); + assertThat(parser.isDdlStatement("SELECT FOO FROM BAR")).isFalse(); + assertThat(parser.isDdlStatement("INSERT INTO FOO (ID, NAME) VALUES (1, 'NAME')")).isFalse(); + assertThat(parser.isDdlStatement("UPDATE FOO SET NAME='NAME' WHERE ID=1")).isFalse(); + assertThat(parser.isDdlStatement("DELETE FROM FOO")).isFalse(); - assertTrue( - parser.isDdlStatement("CREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")); - assertTrue(parser.isDdlStatement("alter table foo add Description string(100)")); - assertTrue(parser.isDdlStatement("drop table foo")); - assertTrue(parser.isDdlStatement("Create index BAR on foo (name)")); + assertThat( + parser.isDdlStatement("CREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) + .isTrue(); + assertThat(parser.isDdlStatement("alter table foo add Description string(100)")).isTrue(); + assertThat(parser.isDdlStatement("drop table foo")).isTrue(); + assertThat(parser.isDdlStatement("Create index BAR on foo (name)")).isTrue(); - assertTrue( - parser - .parse( - Statement.of( - "\t\tCREATE\n\t TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) - .isDdl()); - assertTrue( - parser - .parse( - Statement.of( - "\n\n\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) - .isDdl()); - assertTrue( - parser - .parse( - Statement.of( - "-- this is a comment\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) - .isDdl()); - assertTrue( - parser - .parse( - Statement.of( - "/* multi line comment\n* with more information on the next line\n*/\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) - .isDdl()); - assertTrue( - parser - .parse( - Statement.of( - "/** java doc comment\n* with more information on the next line\n*/\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) - .isDdl()); - assertTrue( - parser - .parse( - Statement.of( - "-- SELECT in a single line comment \nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) - .isDdl()); - assertTrue( - parser - .parse( - Statement.of( - "/* SELECT in a multi line comment\n* with more information on the next line\n*/\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) - .isDdl()); - assertTrue( - parser - .parse( - Statement.of( - "/** SELECT in a java doc comment\n* with more information on the next line\n*/\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) - .isDdl()); + assertThat( + parser + .parse( + Statement.of( + "\t\tCREATE\n\t TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) + .isDdl()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "\n\n\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) + .isDdl()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "-- this is a comment\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) + .isDdl()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "/* multi line comment\n* with more information on the next line\n*/\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) + .isDdl()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "/** java doc comment\n* with more information on the next line\n*/\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) + .isDdl()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "-- SELECT in a single line comment \nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) + .isDdl()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "/* SELECT in a multi line comment\n* with more information on the next line\n*/\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) + .isDdl()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "/** SELECT in a java doc comment\n* with more information on the next line\n*/\nCREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) + .isDdl()) + .isTrue(); assertTrue( parser @@ -298,75 +503,94 @@ public void testIsDdlStatement() { @Test public void testIsQuery() { - assertFalse(parser.isQuery("")); - assertFalse(parser.isQuery("random text")); - assertFalse(parser.isQuery("SELECT1")); - assertFalse(parser.isQuery("SSELECT 1")); - assertTrue(parser.isQuery("SELECT 1")); - assertTrue(parser.isQuery("select 1")); - assertTrue(parser.isQuery("SELECT foo FROM bar WHERE id=@id")); - assertFalse(parser.isQuery("INSERT INTO FOO (ID, NAME) VALUES (1, 'NAME')")); - assertFalse(parser.isQuery("UPDATE FOO SET NAME='NAME' WHERE ID=1")); - assertFalse(parser.isQuery("DELETE FROM FOO")); - assertFalse(parser.isQuery("CREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")); - assertFalse(parser.isQuery("alter table foo add Description string(100)")); - assertFalse(parser.isQuery("drop table foo")); - assertFalse(parser.isQuery("Create index BAR on foo (name)")); - assertTrue(parser.isQuery("select * from foo")); - assertFalse(parser.isQuery("INSERT INTO FOO (ID, NAME) SELECT ID+1, NAME FROM FOO")); + assertThat(parser.isQuery("")).isFalse(); + assertThat(parser.isQuery("random text")).isFalse(); + assertThat(parser.isQuery("SELECT1")).isFalse(); + assertThat(parser.isQuery("SSELECT 1")).isFalse(); - assertTrue( - parser.isQuery( - "WITH subQ1 AS (SELECT SchoolID FROM Roster),\n" - + " subQ2 AS (SELECT OpponentID FROM PlayerStats)\n" - + "SELECT * FROM subQ1\n" - + "UNION ALL\n" - + "SELECT * FROM subQ2")); - assertTrue( - parser.isQuery( - "with subQ1 AS (SELECT SchoolID FROM Roster),\n" - + " subQ2 AS (SELECT OpponentID FROM PlayerStats)\n" - + "select * FROM subQ1\n" - + "UNION ALL\n" - + "SELECT * FROM subQ2")); - assertTrue( - parser - .parse( - Statement.of( - "-- this is a comment\nwith foo as (select * from bar)\nselect * from foo")) - .isQuery()); + assertThat(parser.isQuery("SELECT 1")).isTrue(); + assertThat(parser.isQuery("select 1")).isTrue(); + assertThat(parser.isQuery("SELECT foo FROM bar WHERE id=@id")).isTrue(); - assertTrue(parser.parse(Statement.of("-- this is a comment\nselect * from foo")).isQuery()); - assertTrue( - parser - .parse( - Statement.of( - "/* multi line comment\n* with more information on the next line\n*/\nSELECT ID, NAME\nFROM\tTEST\n\tWHERE ID=1")) - .isQuery()); - assertTrue( - parser - .parse( - Statement.of( - "/** java doc comment\n* with more information on the next line\n*/\nselect max(id) from test")) - .isQuery()); - assertTrue( - parser.parse(Statement.of("-- INSERT in a single line comment \n select 1")).isQuery()); - assertTrue( - parser - .parse( - Statement.of( - "/* UPDATE in a multi line comment\n* with more information on the next line\n*/\nSELECT 1")) - .isQuery()); - assertTrue( - parser - .parse( - Statement.of( - "/** DELETE in a java doc comment\n* with more information on the next line\n*/\n\n\n\n -- UPDATE test\nSELECT 1")) - .isQuery()); + assertThat(parser.isQuery("INSERT INTO FOO (ID, NAME) VALUES (1, 'NAME')")).isFalse(); + assertThat(parser.isQuery("UPDATE FOO SET NAME='NAME' WHERE ID=1")).isFalse(); + assertThat(parser.isQuery("DELETE FROM FOO")).isFalse(); + assertThat(parser.isQuery("CREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)")) + .isFalse(); + assertThat(parser.isQuery("alter table foo add Description string(100)")).isFalse(); + assertThat(parser.isQuery("drop table foo")).isFalse(); + assertThat(parser.isQuery("Create index BAR on foo (name)")).isFalse(); + + assertThat(parser.isQuery("select * from foo")).isTrue(); + + assertThat(parser.isQuery("INSERT INTO FOO (ID, NAME) SELECT ID+1, NAME FROM FOO")).isFalse(); + + assertThat( + parser.isQuery( + "WITH subQ1 AS (SELECT SchoolID FROM Roster),\n" + + " subQ2 AS (SELECT OpponentID FROM PlayerStats)\n" + + "SELECT * FROM subQ1\n" + + "UNION ALL\n" + + "SELECT * FROM subQ2")) + .isTrue(); + assertThat( + parser.isQuery( + "with subQ1 AS (SELECT SchoolID FROM Roster),\n" + + " subQ2 AS (SELECT OpponentID FROM PlayerStats)\n" + + "select * FROM subQ1\n" + + "UNION ALL\n" + + "SELECT * FROM subQ2")) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "-- this is a comment\nwith foo as (select * from bar)\nselect * from foo")) + .isQuery()) + .isTrue(); + + assertThat(parser.parse(Statement.of("-- this is a comment\nselect * from foo")).isQuery()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "/* multi line comment\n* with more information on the next line\n*/\nSELECT ID, NAME\nFROM\tTEST\n\tWHERE ID=1")) + .isQuery()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "/** java doc comment\n* with more information on the next line\n*/\nselect max(id) from test")) + .isQuery()) + .isTrue(); + assertThat( + parser + .parse(Statement.of("-- INSERT in a single line comment \n select 1")) + .isQuery()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "/* UPDATE in a multi line comment\n* with more information on the next line\n*/\nSELECT 1")) + .isQuery()) + .isTrue(); + assertThat( + parser + .parse( + Statement.of( + "/** DELETE in a java doc comment\n* with more information on the next line\n*/\n\n\n\n -- UPDATE test\nSELECT 1")) + .isQuery()) + .isTrue(); } @Test - public void testIsQuery_QueryHints() { + public void testGoogleStandardSQLDialectIsQuery_QueryHints() { + Assume.assumeTrue(dialect == Dialect.GOOGLE_STANDARD_SQL); + + // Supports query hints, PostgreSQL dialect does NOT // Valid query hints. assertTrue(parser.isQuery("@{JOIN_METHOD=HASH_JOIN} SELECT * FROM PersonsTable")); assertTrue(parser.isQuery("@ {JOIN_METHOD=HASH_JOIN} SELECT * FROM PersonsTable")); @@ -390,13 +614,11 @@ public void testIsQuery_QueryHints() { // Multiple query hints. assertTrue( - StatementParser.INSTANCE.isQuery( - "@{FORCE_INDEX=index_name} @{JOIN_METHOD=HASH_JOIN} SELECT * FROM tbl")); + parser.isQuery("@{FORCE_INDEX=index_name} @{JOIN_METHOD=HASH_JOIN} SELECT * FROM tbl")); assertTrue( - StatementParser.INSTANCE.isQuery( - "@{FORCE_INDEX=index_name} @{JOIN_METHOD=HASH_JOIN} Select * FROM tbl")); + parser.isQuery("@{FORCE_INDEX=index_name} @{JOIN_METHOD=HASH_JOIN} Select * FROM tbl")); assertTrue( - StatementParser.INSTANCE.isQuery( + parser.isQuery( "@{FORCE_INDEX=index_name}\n@{JOIN_METHOD=HASH_JOIN}\nWITH subQ1 AS (SELECT SchoolID FROM Roster),\n" + " subQ2 AS (SELECT OpponentID FROM PlayerStats)\n" + "SELECT * FROM subQ1\n" @@ -407,10 +629,16 @@ public void testIsQuery_QueryHints() { assertFalse(parser.isQuery("@{JOIN_METHOD=HASH_JOIN SELECT * FROM PersonsTable")); assertFalse(parser.isQuery("@JOIN_METHOD=HASH_JOIN} SELECT * FROM PersonsTable")); assertFalse(parser.isQuery("@JOIN_METHOD=HASH_JOIN SELECT * FROM PersonsTable")); + assertFalse( + parser.isQuery( + "@{FORCE_INDEX=index_name} @{JOIN_METHOD=HASH_JOIN} UPDATE tbl set FOO=1 WHERE ID=2")); } @Test public void testIsUpdate_QueryHints() { + Assume.assumeTrue(dialect == Dialect.GOOGLE_STANDARD_SQL); + + // Supports query hints, PostgreSQL dialect does NOT // Valid query hints. assertTrue( parser.isUpdateStatement( @@ -439,7 +667,7 @@ public void testIsUpdate_QueryHints() { // Multiple query hints. assertTrue( - StatementParser.INSTANCE.isUpdateStatement( + parser.isUpdateStatement( "@{LOCK_SCANNED_RANGES=exclusive} @{USE_ADDITIONAL_PARALLELISM=TRUE} UPDATE FOO SET NAME='foo' WHERE ID=1")); // Invalid query hints. @@ -652,15 +880,14 @@ private Set getAllStatements() throws CompileException private void assertParsing( String value, Class statementClass) { - assertThat(this.parse(value), is(equalTo(statementClass))); + assertThat(this.parse(value)).isEqualTo(statementClass); } private void testParseStatement( String statement, Class statementClass) { - assertThat( - "\"" + statement + "\" should be " + statementClass.getName(), - this.parse(statement), - is(equalTo(statementClass))); + Truth.assertWithMessage("\"" + statement + "\" should be " + statementClass.getName()) + .that(this.parse(statement)) + .isEqualTo(statementClass); assertParsing(upper(statement), statementClass); assertParsing(lower(statement), statementClass); assertParsing(withSpaces(statement), statementClass); @@ -673,39 +900,37 @@ private void testParseStatement( assertParsing(withTrailingTabs(statement), statementClass); assertParsing(withTrailingLinefeeds(statement), statementClass); - assertThat(parse(withInvalidPrefix(statement)), is(nullValue())); - assertThat(parse(withInvalidSuffix(statement)), is(nullValue())); - - assertNull(parse(withPrefix("%", statement))); - assertNull(parse(withPrefix("_", statement))); - assertNull(parse(withPrefix("&", statement))); - assertNull(parse(withPrefix("$", statement))); - assertNull(parse(withPrefix("@", statement))); - assertNull(parse(withPrefix("!", statement))); - assertNull(parse(withPrefix("*", statement))); - assertNull(parse(withPrefix("(", statement))); - assertNull(parse(withPrefix(")", statement))); - - assertThat( - withSuffix("%", statement) + " is not a valid statement", - parse(withSuffix("%", statement)), - is(nullValue())); - assertNull(parse(withSuffix("_", statement))); - assertNull(parse(withSuffix("&", statement))); - assertNull(parse(withSuffix("$", statement))); - assertNull(parse(withSuffix("@", statement))); - assertNull(parse(withSuffix("!", statement))); - assertNull(parse(withSuffix("*", statement))); - assertNull(parse(withSuffix("(", statement))); - assertNull(parse(withSuffix(")", statement))); + assertThat(parse(withInvalidPrefix(statement))).isNull(); + assertThat(parse(withInvalidSuffix(statement))).isNull(); + + assertThat(parse(withPrefix("%", statement))).isNull(); + assertThat(parse(withPrefix("_", statement))).isNull(); + assertThat(parse(withPrefix("&", statement))).isNull(); + assertThat(parse(withPrefix("$", statement))).isNull(); + assertThat(parse(withPrefix("@", statement))).isNull(); + assertThat(parse(withPrefix("!", statement))).isNull(); + assertThat(parse(withPrefix("*", statement))).isNull(); + assertThat(parse(withPrefix("(", statement))).isNull(); + assertThat(parse(withPrefix(")", statement))).isNull(); + + Truth.assertWithMessage(withSuffix("%", statement) + " is not a valid statement") + .that(parse(withSuffix("%", statement))) + .isNull(); + assertThat(parse(withSuffix("_", statement))).isNull(); + assertThat(parse(withSuffix("&", statement))).isNull(); + assertThat(parse(withSuffix("$", statement))).isNull(); + assertThat(parse(withSuffix("@", statement))).isNull(); + assertThat(parse(withSuffix("!", statement))).isNull(); + assertThat(parse(withSuffix("*", statement))).isNull(); + assertThat(parse(withSuffix("(", statement))).isNull(); + assertThat(parse(withSuffix(")", statement))).isNull(); } private void testParseStatementWithOneParameterAtTheEnd( String statement, Class statementClass) { - assertThat( - "\"" + statement + "\" should be " + statementClass.getName(), - this.parse(statement), - is(equalTo(statementClass))); + Truth.assertWithMessage("\"" + statement + "\" should be " + statementClass.getName()) + .that(this.parse(statement)) + .isEqualTo(statementClass); assertParsing(upper(statement), statementClass); assertParsing(lower(statement), statementClass); assertParsing(withSpaces(statement), statementClass); @@ -718,18 +943,18 @@ private void testParseStatementWithOneParame assertParsing(withTrailingTabs(statement), statementClass); assertParsing(withTrailingLinefeeds(statement), statementClass); - assertNull(parse(withInvalidPrefix(statement))); + assertThat(parse(withInvalidPrefix(statement))).isNull(); assertParsing(withInvalidSuffix(statement), statementClass); - assertNull(parse(withPrefix("%", statement))); - assertNull(parse(withPrefix("_", statement))); - assertNull(parse(withPrefix("&", statement))); - assertNull(parse(withPrefix("$", statement))); - assertNull(parse(withPrefix("@", statement))); - assertNull(parse(withPrefix("!", statement))); - assertNull(parse(withPrefix("*", statement))); - assertNull(parse(withPrefix("(", statement))); - assertNull(parse(withPrefix(")", statement))); + assertThat(parse(withPrefix("%", statement))).isNull(); + assertThat(parse(withPrefix("_", statement))).isNull(); + assertThat(parse(withPrefix("&", statement))).isNull(); + assertThat(parse(withPrefix("$", statement))).isNull(); + assertThat(parse(withPrefix("@", statement))).isNull(); + assertThat(parse(withPrefix("!", statement))).isNull(); + assertThat(parse(withPrefix("*", statement))).isNull(); + assertThat(parse(withPrefix("(", statement))).isNull(); + assertThat(parse(withPrefix(")", statement))).isNull(); assertParsing(withSuffix("%", statement), statementClass); assertParsing(withSuffix("_", statement), statementClass); @@ -742,6 +967,337 @@ private void testParseStatementWithOneParame assertParsing(withSuffix(")", statement), statementClass); } + @Test + public void testConvertPositionalParametersToNamedParametersWithGsqlException() { + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "/*GSQL*/select * from foo where name=?") + .sqlWithNamedParameters) + .isEqualTo("/*GSQL*/select * from foo where name=@p1"); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "/*GSQL*/?'?test?\"?test?\"?'?") + .sqlWithNamedParameters) + .isEqualTo("/*GSQL*/@p1'?test?\"?test?\"?'@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "/*GSQL*/?'?it\\'?s'?") + .sqlWithNamedParameters) + .isEqualTo("/*GSQL*/@p1'?it\\'?s'@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "/*GSQL*/?'?it\\\"?s'?") + .sqlWithNamedParameters) + .isEqualTo("/*GSQL*/@p1'?it\\\"?s'@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "/*GSQL*/?\"?it\\\"?s\"?") + .sqlWithNamedParameters) + .isEqualTo("/*GSQL*/@p1\"?it\\\"?s\"@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "/*GSQL*/?'''?it\\'?s'''?") + .sqlWithNamedParameters) + .isEqualTo("/*GSQL*/@p1'''?it\\'?s'''@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "/*GSQL*/?\"\"\"?it\\\"?s\"\"\"?") + .sqlWithNamedParameters) + .isEqualTo("/*GSQL*/@p1\"\"\"?it\\\"?s\"\"\"@p2"); + + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', + "/*GSQL*/select 1, ?, 'test?test', \"test?test\", foo.* from `foo` where col1=? and col2='test' and col3=? and col4='?' and col5=\"?\" and col6='?''?''?'") + .sqlWithNamedParameters, + is( + equalTo( + "/*GSQL*/select 1, @p1, 'test?test', \"test?test\", foo.* from `foo` where col1=@p2 and col2='test' and col3=@p3 and col4='?' and col5=\"?\" and col6='?''?''?'"))); + + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', + "/*GSQL*/select * " + + "from foo " + + "where name=? " + + "and col2 like ? " + + "and col3 > ?") + .sqlWithNamedParameters, + is( + equalTo( + "/*GSQL*/select * " + + "from foo " + + "where name=@p1 " + + "and col2 like @p2 " + + "and col3 > @p3"))); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "/*GSQL*/select * " + "from foo " + "where id between ? and ?") + .sqlWithNamedParameters, + is(equalTo("/*GSQL*/select * " + "from foo " + "where id between @p1 and @p2"))); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "/*GSQL*/select * " + "from foo " + "limit ? offset ?") + .sqlWithNamedParameters, + is(equalTo("/*GSQL*/select * " + "from foo " + "limit @p1 offset @p2"))); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', + "/*GSQL*/select * " + + "from foo " + + "where col1=? " + + "and col2 like ? " + + "and col3 > ? " + + "and col4 < ? " + + "and col5 != ? " + + "and col6 not in (?, ?, ?) " + + "and col7 in (?, ?, ?) " + + "and col8 between ? and ?") + .sqlWithNamedParameters, + is( + equalTo( + "/*GSQL*/select * " + + "from foo " + + "where col1=@p1 " + + "and col2 like @p2 " + + "and col3 > @p3 " + + "and col4 < @p4 " + + "and col5 != @p5 " + + "and col6 not in (@p6, @p7, @p8) " + + "and col7 in (@p9, @p10, @p11) " + + "and col8 between @p12 and @p13"))); + } + + @Test + public void testGoogleStandardSQLDialectConvertPositionalParametersToNamedParameters() { + Assume.assumeTrue(dialect == Dialect.GOOGLE_STANDARD_SQL); + + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "select * from foo where name=?") + .sqlWithNamedParameters) + .isEqualTo("select * from foo where name=@p1"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?'?test?\"?test?\"?'?") + .sqlWithNamedParameters) + .isEqualTo("@p1'?test?\"?test?\"?'@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?'?it\\'?s'?") + .sqlWithNamedParameters) + .isEqualTo("@p1'?it\\'?s'@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?'?it\\\"?s'?") + .sqlWithNamedParameters) + .isEqualTo("@p1'?it\\\"?s'@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?\"?it\\\"?s\"?") + .sqlWithNamedParameters) + .isEqualTo("@p1\"?it\\\"?s\"@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?'''?it\\'?s'''?") + .sqlWithNamedParameters) + .isEqualTo("@p1'''?it\\'?s'''@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?\"\"\"?it\\\"?s\"\"\"?") + .sqlWithNamedParameters) + .isEqualTo("@p1\"\"\"?it\\\"?s\"\"\"@p2"); + + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?`?it\\`?s`?") + .sqlWithNamedParameters) + .isEqualTo("@p1`?it\\`?s`@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?```?it\\`?s```?") + .sqlWithNamedParameters) + .isEqualTo("@p1```?it\\`?s```@p2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?'''?it\\'?s \n ?it\\'?s'''?") + .sqlWithNamedParameters) + .isEqualTo("@p1'''?it\\'?s \n ?it\\'?s'''@p2"); + + assertUnclosedLiteral("?'?it\\'?s \n ?it\\'?s'?"); + assertUnclosedLiteral("?'?it\\'?s \n ?it\\'?s?"); + assertUnclosedLiteral("?'''?it\\'?s \n ?it\\'?s'?"); + + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', + "select 1, ?, 'test?test', \"test?test\", foo.* from `foo` where col1=? and col2='test' and col3=? and col4='?' and col5=\"?\" and col6='?''?''?'") + .sqlWithNamedParameters, + is( + equalTo( + "select 1, @p1, 'test?test', \"test?test\", foo.* from `foo` where col1=@p2 and col2='test' and col3=@p3 and col4='?' and col5=\"?\" and col6='?''?''?'"))); + + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', + "select * " + "from foo " + "where name=? " + "and col2 like ? " + "and col3 > ?") + .sqlWithNamedParameters, + is( + equalTo( + "select * " + + "from foo " + + "where name=@p1 " + + "and col2 like @p2 " + + "and col3 > @p3"))); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "select * " + "from foo " + "where id between ? and ?") + .sqlWithNamedParameters, + is(equalTo("select * " + "from foo " + "where id between @p1 and @p2"))); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "select * " + "from foo " + "limit ? offset ?") + .sqlWithNamedParameters, + is(equalTo("select * " + "from foo " + "limit @p1 offset @p2"))); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', + "select * " + + "from foo " + + "where col1=? " + + "and col2 like ? " + + "and col3 > ? " + + "and col4 < ? " + + "and col5 != ? " + + "and col6 not in (?, ?, ?) " + + "and col7 in (?, ?, ?) " + + "and col8 between ? and ?") + .sqlWithNamedParameters, + is( + equalTo( + "select * " + + "from foo " + + "where col1=@p1 " + + "and col2 like @p2 " + + "and col3 > @p3 " + + "and col4 < @p4 " + + "and col5 != @p5 " + + "and col6 not in (@p6, @p7, @p8) " + + "and col7 in (@p9, @p10, @p11) " + + "and col8 between @p12 and @p13"))); + } + + @Test + public void testPostgreSQLDialectDialectConvertPositionalParametersToNamedParameters() { + Assume.assumeTrue(dialect == Dialect.POSTGRESQL); + + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "select * from foo where name=?") + .sqlWithNamedParameters) + .isEqualTo("select * from foo where name=$1"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?'?test?\"?test?\"?'?") + .sqlWithNamedParameters) + .isEqualTo("$1'?test?\"?test?\"?'$2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?'?it\\'?s'?") + .sqlWithNamedParameters) + .isEqualTo("$1'?it\\'?s'$2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?'?it\\\"?s'?") + .sqlWithNamedParameters) + .isEqualTo("$1'?it\\\"?s'$2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?\"?it\\\"?s\"?") + .sqlWithNamedParameters) + .isEqualTo("$1\"?it\\\"?s\"$2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?'''?it\\'?s'''?") + .sqlWithNamedParameters) + .isEqualTo("$1'''?it\\'?s'''$2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?\"\"\"?it\\\"?s\"\"\"?") + .sqlWithNamedParameters) + .isEqualTo("$1\"\"\"?it\\\"?s\"\"\"$2"); + + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?$$?it$?s$$?") + .sqlWithNamedParameters) + .isEqualTo("$1$$?it$?s$$$2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?$tag$?it$$?s$tag$?") + .sqlWithNamedParameters) + .isEqualTo("$1$tag$?it$$?s$tag$$2"); + assertThat( + parser.convertPositionalParametersToNamedParameters('?', "?$$?it\\'?s \n ?it\\'?s$$?") + .sqlWithNamedParameters) + .isEqualTo("$1$$?it\\'?s \n ?it\\'?s$$$2"); + + assertUnclosedLiteral("?'?it\\'?s \n ?it\\'?s'?"); + assertUnclosedLiteral("?'?it\\'?s \n ?it\\'?s?"); + assertUnclosedLiteral("?'''?it\\'?s \n ?it\\'?s'?"); + + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', + "select 1, ?, 'test?test', \"test?test\", foo.* from `foo` where col1=? and col2='test' and col3=? and col4='?' and col5=\"?\" and col6='?''?''?'") + .sqlWithNamedParameters, + is( + equalTo( + "select 1, $1, 'test?test', \"test?test\", foo.* from `foo` where col1=$2 and col2='test' and col3=$3 and col4='?' and col5=\"?\" and col6='?''?''?'"))); + + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', + "select * " + "from foo " + "where name=? " + "and col2 like ? " + "and col3 > ?") + .sqlWithNamedParameters, + is( + equalTo( + "select * " + + "from foo " + + "where name=$1 " + + "and col2 like $2 " + + "and col3 > $3"))); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "select * " + "from foo " + "where id between ? and ?") + .sqlWithNamedParameters, + is(equalTo("select * " + "from foo " + "where id between $1 and $2"))); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', "select * " + "from foo " + "limit ? offset ?") + .sqlWithNamedParameters, + is(equalTo("select * " + "from foo " + "limit $1 offset $2"))); + assertThat( + parser.convertPositionalParametersToNamedParameters( + '?', + "select * " + + "from foo " + + "where col1=? " + + "and col2 like ? " + + "and col3 > ? " + + "and col4 < ? " + + "and col5 != ? " + + "and col6 not in (?, ?, ?) " + + "and col7 in (?, ?, ?) " + + "and col8 between ? and ?") + .sqlWithNamedParameters, + is( + equalTo( + "select * " + + "from foo " + + "where col1=$1 " + + "and col2 like $2 " + + "and col3 > $3 " + + "and col4 < $4 " + + "and col5 != $5 " + + "and col6 not in ($6, $7, $8) " + + "and col7 in ($9, $10, $11) " + + "and col8 between $12 and $13"))); + } + + private void assertUnclosedLiteral(String sql) { + try { + parser.convertPositionalParametersToNamedParameters('?', sql); + fail("missing expected exception"); + } catch (SpannerException e) { + assertThat(e.getErrorCode()).isSameInstanceAs(ErrorCode.INVALID_ARGUMENT); + assertThat(e.getMessage()) + .startsWith( + ErrorCode.INVALID_ARGUMENT.name() + + ": SQL statement contains an unclosed literal: " + + sql); + } + } + @SuppressWarnings("unchecked") private Class parse(String statement) { ClientSideStatementImpl optional = parser.parseClientSideStatement(statement); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/TestChannelProvider.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/TestChannelProvider.java new file mode 100644 index 00000000000..7331c8d03c7 --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/TestChannelProvider.java @@ -0,0 +1,26 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner.connection; + +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.cloud.spanner.v1.SpannerSettings; + +public final class TestChannelProvider implements ConnectionOptions.ExternalChannelProvider { + public TransportChannelProvider getChannelProvider(String host, int port) { + return SpannerSettings.defaultTransportChannelProvider(); + } +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/DialectTestParameter.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/DialectTestParameter.java new file mode 100644 index 00000000000..bb17bed5512 --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/DialectTestParameter.java @@ -0,0 +1,50 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner.it; + +import com.google.cloud.spanner.Dialect; +import java.util.Map; + +public class DialectTestParameter { + + final Dialect dialect; + final String createTableFile; + final Map executeQueriesFiles; + final String[] queries; + + DialectTestParameter( + Dialect dialect, + String createTableFile, + Map executeQueriesFiles, + String[] queries) { + this.dialect = dialect; + this.createTableFile = createTableFile; + this.executeQueriesFiles = executeQueriesFiles; + this.queries = queries; + } + + DialectTestParameter(Dialect dialect) { + this.dialect = dialect; + this.createTableFile = ""; + this.executeQueriesFiles = null; + this.queries = null; + } + + public String toString() { + return this.dialect.name(); + } +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchReadTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchReadTest.java index 94c3723439a..ed9484c5632 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchReadTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITBatchReadTest.java @@ -16,7 +16,9 @@ package com.google.cloud.spanner.it; +import static com.google.cloud.spanner.testing.EmulatorSpannerHelper.isUsingEmulator; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assume.assumeFalse; import com.google.cloud.ByteArray; import com.google.cloud.Timestamp; @@ -25,6 +27,7 @@ import com.google.cloud.spanner.BatchTransactionId; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.IntegrationTestEnv; import com.google.cloud.spanner.KeySet; import com.google.cloud.spanner.Mutation; @@ -34,6 +37,7 @@ import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.TimestampBound; +import com.google.common.collect.ImmutableList; import com.google.common.hash.HashFunction; import com.google.common.hash.Hashing; import java.util.ArrayList; @@ -50,32 +54,46 @@ import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; /** * Integration test reading large amounts of data using the Batch APIs. The size of data ensures * that multiple partitions are returned by the server. */ @Category(ParallelIntegrationTest.class) -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public class ITBatchReadTest { private static int numRows; private static final int WRITE_BATCH_SIZE = 1 << 20; private static final String TABLE_NAME = "BatchTestTable"; private static final String INDEX_NAME = "TestIndexByValue"; - private static final long STALENESS_MILLISEC = 1 * 1000; + private static final long STALENESS_MILLISEC = 1000; @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); - private static Database db; private static HashFunction hasher; - private static DatabaseClient dbClient; - private static BatchClient client; + private static BatchClient googleStandardSQLBatchClient; + private static BatchClient postgreSQLBatchClient; private static final Random RANDOM = new Random(); private BatchReadOnlyTransaction batchTxn; + @Parameters(name = "Dialect = {0}") + public static List data() { + List params = new ArrayList<>(); + params.add(new DialectTestParameter(Dialect.GOOGLE_STANDARD_SQL)); + // PG dialect tests are not supported by the emulator + if (!isUsingEmulator()) { + params.add(new DialectTestParameter(Dialect.POSTGRESQL)); + } + return params; + } + + @Parameter public DialectTestParameter dialect; + // Generate a large number of rows to allow multiple read/query partitions. private static List manyRows() { List rows = new ArrayList<>(); @@ -88,7 +106,7 @@ private static List manyRows() { @BeforeClass public static void setUpDatabase() throws Exception { - db = + Database googleStandardDatabase = env.getTestHelper() .createTestDatabase( "CREATE TABLE " @@ -101,46 +119,86 @@ public static void setUpDatabase() throws Exception { + ") PRIMARY KEY (Key)", "CREATE INDEX " + INDEX_NAME + " ON " + TABLE_NAME + "(Fingerprint)"); hasher = Hashing.goodFastHash(64); - dbClient = env.getTestHelper().getDatabaseClient(db); - client = env.getTestHelper().getBatchClient(db); - - List mutations = new ArrayList<>(); - int totalSize = 0; - int i = 0; - for (int row : manyRows()) { - numRows++; - byte[] data = new byte[row]; - RANDOM.nextBytes(data); - mutations.add( - Mutation.newInsertOrUpdateBuilder(TABLE_NAME) - .set("Key") - .to(i) - .set("Data") - .to(ByteArray.copyFrom(data)) - .set("Fingerprint") - .to(hasher.hashBytes(data).asLong()) - .set("Size") - .to(row) - .build()); - totalSize += row; - i++; - if (totalSize >= WRITE_BATCH_SIZE) { - dbClient.write(mutations); - mutations.clear(); - totalSize = 0; + googleStandardSQLBatchClient = env.getTestHelper().getBatchClient(googleStandardDatabase); + + List databaseClients = new ArrayList<>(); + databaseClients.add(env.getTestHelper().getDatabaseClient(googleStandardDatabase)); + + if (!isUsingEmulator()) { + Database postgreSQLDatabase = + env.getTestHelper().createTestDatabase(Dialect.POSTGRESQL, Collections.emptyList()); + env.getTestHelper() + .getClient() + .getDatabaseAdminClient() + .updateDatabaseDdl( + env.getTestHelper().getInstanceId().getInstance(), + postgreSQLDatabase.getId().getDatabase(), + ImmutableList.of( + "CREATE TABLE " + + TABLE_NAME + + " (" + + " Key bigint not null primary key," + + " Data bytea," + + " Fingerprint bigint," + + " Size bigint" + + ")", + "CREATE INDEX " + INDEX_NAME + " ON " + TABLE_NAME + "(Fingerprint)"), + null) + .get(); + postgreSQLBatchClient = env.getTestHelper().getBatchClient(postgreSQLDatabase); + databaseClients.add(env.getTestHelper().getDatabaseClient(postgreSQLDatabase)); + } + + List rows = manyRows(); + numRows = rows.size(); + for (DatabaseClient dbClient : databaseClients) { + List mutations = new ArrayList<>(); + int totalSize = 0; + int i = 0; + for (int row : rows) { + byte[] data = new byte[row]; + RANDOM.nextBytes(data); + mutations.add( + Mutation.newInsertOrUpdateBuilder(TABLE_NAME) + .set("Key") + .to(i) + .set("Data") + .to(ByteArray.copyFrom(data)) + .set("Fingerprint") + .to(hasher.hashBytes(data).asLong()) + .set("Size") + .to(row) + .build()); + totalSize += row; + i++; + if (totalSize >= WRITE_BATCH_SIZE) { + dbClient.write(mutations); + mutations.clear(); + totalSize = 0; + } } + dbClient.write(mutations); } - dbClient.write(mutations); // Our read/queries are executed with some staleness. Thread.sleep(2 * STALENESS_MILLISEC); } + private BatchClient getBatchClient() { + if (dialect.dialect == Dialect.POSTGRESQL) { + return postgreSQLBatchClient; + } + return googleStandardSQLBatchClient; + } + @Test public void read() { + assumeFalse( + "PostgreSQL does not support the PartitionRead RPC", dialect.dialect == Dialect.POSTGRESQL); + BitSet seenRows = new BitSet(numRows); TimestampBound bound = getRandomBound(); PartitionOptions partitionParams = getRandomPartitionOptions(); - batchTxn = client.batchReadOnlyTransaction(bound); + batchTxn = getBatchClient().batchReadOnlyTransaction(bound); List partitions = batchTxn.partitionRead( partitionParams, @@ -153,9 +211,12 @@ public void read() { @Test public void readUsingIndex() { + assumeFalse( + "PostgreSQL does not support the PartitionRead RPC", dialect.dialect == Dialect.POSTGRESQL); + TimestampBound bound = getRandomBound(); PartitionOptions partitionParams = getRandomPartitionOptions(); - batchTxn = client.batchReadOnlyTransaction(bound); + batchTxn = getBatchClient().batchReadOnlyTransaction(bound); List partitions = batchTxn.partitionReadUsingIndex( partitionParams, @@ -166,7 +227,8 @@ public void readUsingIndex() { BatchTransactionId txnID = batchTxn.getBatchTransactionId(); int numRowsRead = 0; for (Partition p : partitions) { - BatchReadOnlyTransaction batchTxnOnEachWorker = client.batchReadOnlyTransaction(txnID); + BatchReadOnlyTransaction batchTxnOnEachWorker = + getBatchClient().batchReadOnlyTransaction(txnID); try (ResultSet result = batchTxnOnEachWorker.execute(p)) { while (result.next()) { numRowsRead++; @@ -188,7 +250,7 @@ public void query() { BitSet seenRows = new BitSet(numRows); TimestampBound bound = getRandomBound(); PartitionOptions partitionParams = getRandomPartitionOptions(); - batchTxn = client.batchReadOnlyTransaction(bound); + batchTxn = getBatchClient().batchReadOnlyTransaction(bound); List partitions = batchTxn.partitionQuery( partitionParams, @@ -227,7 +289,8 @@ private TimestampBound getRandomBound() { private void fetchAndValidateRows( List partitions, BatchTransactionId txnID, BitSet seenRows) { for (Partition p : partitions) { - BatchReadOnlyTransaction batchTxnOnEachWorker = client.batchReadOnlyTransaction(txnID); + BatchReadOnlyTransaction batchTxnOnEachWorker = + getBatchClient().batchReadOnlyTransaction(txnID); try (ResultSet result = batchTxnOnEachWorker.execute(p)) { // validate no duplicate rows; verify all columns read. validate(result, seenRows); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDMLTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDMLTest.java index 2a94ed82abb..2c7a8da27c3 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDMLTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDMLTest.java @@ -16,12 +16,14 @@ package com.google.cloud.spanner.it; +import static com.google.cloud.spanner.testing.EmulatorSpannerHelper.isUsingEmulator; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.IntegrationTestEnv; import com.google.cloud.spanner.Key; @@ -36,22 +38,27 @@ import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.TransactionRunner; import com.google.cloud.spanner.TransactionRunner.TransactionCallable; +import com.google.cloud.spanner.connection.ConnectionOptions; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.List; +import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; /** Integration tests for DML. */ @Category(ParallelIntegrationTest.class) -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public final class ITDMLTest { @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); - private static Database db; - private static DatabaseClient client; + private static DatabaseClient googleStandardSQLClient; + private static DatabaseClient postgreSQLClient; /** Sequence for assigning unique keys to test cases. */ private static int seq; @@ -60,30 +67,65 @@ public final class ITDMLTest { private static final String INSERT_DML = "INSERT INTO T (k, v) VALUES ('%d-boo1', 1), ('%d-boo2', 2), ('%d-boo3', 3), ('%d-boo4', 4);"; - private static final String UPDATE_DML = "UPDATE T SET T.V = 100 WHERE T.K LIKE '%d-boo%%';"; - private static final String DELETE_DML = "DELETE FROM T WHERE T.K like '%d-boo%%';"; + private static final String UPDATE_DML = "UPDATE T SET V = 100 WHERE K LIKE '%d-boo%%';"; + private static final String DELETE_DML = "DELETE FROM T WHERE K like '%d-boo%%';"; + private static final long DML_COUNT = 4; private static boolean throwAbortOnce = false; @BeforeClass public static void setUpDatabase() { - db = + Database googleStandardSQLDatabase = env.getTestHelper() .createTestDatabase( "CREATE TABLE T (" + " K STRING(MAX) NOT NULL," + " V INT64," + ") PRIMARY KEY (K)"); - client = env.getTestHelper().getDatabaseClient(db); + googleStandardSQLClient = env.getTestHelper().getDatabaseClient(googleStandardSQLDatabase); + if (!isUsingEmulator()) { + Database postgreSQLDatabase = + env.getTestHelper() + .createTestDatabase( + Dialect.POSTGRESQL, + Arrays.asList( + "CREATE TABLE T (" + " K VARCHAR PRIMARY KEY," + " V BIGINT" + ")")); + postgreSQLClient = env.getTestHelper().getDatabaseClient(postgreSQLDatabase); + } + } + + @AfterClass + public static void teardown() { + ConnectionOptions.closeSpanner(); } @Before public void increaseTestIdAndDeleteTestData() { - client.writeAtLeastOnce(Collections.singletonList(Mutation.delete("T", KeySet.all()))); + if (dialect.dialect == Dialect.GOOGLE_STANDARD_SQL) { + googleStandardSQLClient.writeAtLeastOnce( + Collections.singletonList(Mutation.delete("T", KeySet.all()))); + } else { + postgreSQLClient.writeAtLeastOnce( + Collections.singletonList(Mutation.delete("T", KeySet.all()))); + } id++; } + @Parameterized.Parameters(name = "Dialect = {0}") + public static List data() { + List params = new ArrayList<>(); + params.add(new DialectTestParameter(Dialect.GOOGLE_STANDARD_SQL)); + // "PG dialect tests are not supported by the emulator" + if (!isUsingEmulator()) { + params.add(new DialectTestParameter(Dialect.POSTGRESQL)); + } + return params; + } + + @Parameterized.Parameter(0) + public DialectTestParameter dialect; + private static String uniqueKey() { return "k" + seq++; } @@ -114,11 +156,18 @@ private void executeUpdate(long expectedCount, final String... stmts) { } return rowCount; }; - TransactionRunner runner = client.readWriteTransaction(); + TransactionRunner runner = getClient(dialect.dialect).readWriteTransaction(); Long rowCount = runner.run(callable); assertThat(rowCount).isEqualTo(expectedCount); } + private DatabaseClient getClient(Dialect dialect) { + if (dialect == Dialect.POSTGRESQL) { + return postgreSQLClient; + } + return googleStandardSQLClient; + } + @Test public void abortOnceShouldSucceedAfterRetry() { try { @@ -134,27 +183,27 @@ public void abortOnceShouldSucceedAfterRetry() { public void partitionedDML() { executeUpdate(DML_COUNT, insertDml()); assertThat( - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V")) .getLong(0)) .isEqualTo(1); - long rowCount = client.executePartitionedUpdate(Statement.of(updateDml())); + long rowCount = getClient(dialect.dialect).executePartitionedUpdate(Statement.of(updateDml())); // Note: With PDML there is a possibility of network replay or partial update to occur, causing // this assert to fail. We should remove this assert if it is a recurring failure in IT tests. assertThat(rowCount).isEqualTo(DML_COUNT); assertThat( - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V")) .getLong(0)) .isEqualTo(100); - rowCount = client.executePartitionedUpdate(Statement.of(deleteDml())); + rowCount = getClient(dialect.dialect).executePartitionedUpdate(Statement.of(deleteDml())); assertThat(rowCount).isEqualTo(DML_COUNT); assertThat( - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V"))) .isNull(); @@ -164,21 +213,21 @@ public void partitionedDML() { public void standardDML() { executeUpdate(DML_COUNT, insertDml()); assertThat( - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V")) .getLong(0)) .isEqualTo(1); executeUpdate(DML_COUNT, updateDml()); assertThat( - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V")) .getLong(0)) .isEqualTo(100); executeUpdate(DML_COUNT, deleteDml()); assertThat( - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V"))) .isNull(); @@ -208,7 +257,7 @@ public void standardDMLWithDuplicates() { String.format("UPDATE T SET v = 400 WHERE k = '%d-boo1';", id), String.format("UPDATE T SET v = 500 WHERE k = '%d-boo1';", id)); assertThat( - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRow("T", Key.of(String.format("%d-boo1", id)), Collections.singletonList("V")) .getLong(0)) @@ -235,7 +284,7 @@ public void standardDMLReadYourWrites() { .isEqualTo(2 * 2); return null; }; - TransactionRunner runner = client.readWriteTransaction(); + TransactionRunner runner = getClient(dialect.dialect).readWriteTransaction(); runner.run(callable); executeUpdate(DML_COUNT, deleteDml()); @@ -256,7 +305,7 @@ class UserException extends Exception { }; try { - TransactionRunner runner = client.readWriteTransaction(); + TransactionRunner runner = getClient(dialect.dialect).readWriteTransaction(); runner.run(callable); fail("Expected user exception"); } catch (SpannerException e) { @@ -266,7 +315,7 @@ class UserException extends Exception { } ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .read( "T", @@ -292,13 +341,13 @@ public void standardDMLAndMutations() { Mutation.newInsertOrUpdateBuilder("T").set("K").to(key2).set("V").to(2).build()); return null; }; - TransactionRunner runner = client.readWriteTransaction(); + TransactionRunner runner = getClient(dialect.dialect).readWriteTransaction(); runner.run(callable); KeySet.Builder keys = KeySet.newBuilder(); keys.addKey(Key.of(key1)).addKey(Key.of(key2)); ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .read("T", keys.build(), Collections.singletonList("K")); int rowCount = 0; @@ -320,7 +369,7 @@ private void executeQuery(long expectedCount, final String... stmts) { } return rowCount; }; - TransactionRunner runner = client.readWriteTransaction(); + TransactionRunner runner = getClient(dialect.dialect).readWriteTransaction(); Long rowCount = runner.run(callable); assertThat(rowCount).isEqualTo(expectedCount); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminDialectAwareTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminDialectAwareTest.java new file mode 100644 index 00000000000..584dc1fc247 --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminDialectAwareTest.java @@ -0,0 +1,120 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner.it; + +import static com.google.cloud.spanner.testing.EmulatorSpannerHelper.isUsingEmulator; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; + +import com.google.cloud.spanner.Database; +import com.google.cloud.spanner.DatabaseAdminClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Dialect; +import com.google.cloud.spanner.IntegrationTestEnv; +import com.google.cloud.spanner.ParallelIntegrationTest; +import com.google.cloud.spanner.testing.RemoteSpannerHelper; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import java.util.stream.StreamSupport; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +/** Dialect aware integration tests for {@link com.google.cloud.spanner.DatabaseAdminClient}. */ +@Category(ParallelIntegrationTest.class) +@RunWith(Parameterized.class) +public class ITDatabaseAdminDialectAwareTest { + + @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); + private static final Duration OPERATION_TIMEOUT = Duration.ofMinutes(20); + private DatabaseAdminClient client; + private RemoteSpannerHelper testHelper; + private List databases; + + @Parameter public Dialect dialect; + + @Parameters(name = "dialect = {0}") + public static Object[] data() { + return Dialect.values(); + } + + @Before + public void setUp() { + testHelper = env.getTestHelper(); + client = testHelper.getClient().getDatabaseAdminClient(); + databases = new ArrayList<>(); + } + + @After + public void tearDown() { + if (databases != null) { + for (DatabaseId id : databases) { + try { + client.dropDatabase(id.getInstanceId().getInstance(), id.getDatabase()); + } catch (Exception e) { + System.err.println("Could not drop database " + id + ", skipping...: " + e.getMessage()); + } + } + } + } + + @Test + public void testCreateDatabaseWithDialect() throws Exception { + assumeFalse("emulator does not support different dialects", isUsingEmulator()); + + final String projectId = testHelper.getInstanceId().getProject(); + final String instanceId = testHelper.getInstanceId().getInstance(); + final String databaseId = testHelper.getUniqueDatabaseId(); + + final Database databaseToCreate = + client + .newDatabaseBuilder(DatabaseId.of(projectId, instanceId, databaseId)) + .setDialect(dialect) + .build(); + databases.add(databaseToCreate.getId()); + + // Creates the database with the dialect set + final Database createdDatabase = + client + .createDatabase(databaseToCreate, Collections.emptyList()) + .get(OPERATION_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); + assertEquals(dialect, createdDatabase.getDialect()); + + // Test dialect in database retrieval + final Database retrievedDatabase = client.getDatabase(instanceId, databaseId); + assertEquals(dialect, retrievedDatabase.getDialect()); + + // Test dialect database listing + final Optional maybeListedDatabase = + StreamSupport.stream(client.listDatabases(instanceId).iterateAll().spliterator(), false) + .filter(database -> database.getId().getDatabase().equals(databaseId)) + .findFirst(); + assertTrue("Expected to find database in list", maybeListedDatabase.isPresent()); + assertEquals(dialect, maybeListedDatabase.get().getDialect()); + } +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminTest.java index 5559177d537..bc9a075e0ca 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDatabaseAdminTest.java @@ -17,12 +17,15 @@ package com.google.cloud.spanner.it; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.paging.Page; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseAdminClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.IntegrationTestEnv; import com.google.cloud.spanner.Options; @@ -31,11 +34,11 @@ import com.google.cloud.spanner.testing.RemoteSpannerHelper; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; -import com.google.common.collect.Iterators; import com.google.spanner.admin.database.v1.CreateDatabaseMetadata; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; @@ -70,44 +73,52 @@ public void tearDown() { } @Test - public void databaseOperations() throws Exception { - String dbId = testHelper.getUniqueDatabaseId(); - String instanceId = testHelper.getInstanceId().getInstance(); - String statement1 = "CREATE TABLE T (\n" + " K STRING(MAX),\n" + ") PRIMARY KEY(K)"; - OperationFuture op = - dbAdminClient.createDatabase(instanceId, dbId, ImmutableList.of(statement1)); - Database db = op.get(TIMEOUT_MINUTES, TimeUnit.MINUTES); - dbs.add(db); - assertThat(db.getId().getDatabase()).isEqualTo(dbId); - - db = dbAdminClient.getDatabase(instanceId, dbId); - assertThat(db.getId().getDatabase()).isEqualTo(dbId); - - boolean foundDb = false; - for (Database dbInList : - Iterators.toArray( - dbAdminClient.listDatabases(instanceId).iterateAll().iterator(), Database.class)) { - if (dbInList.getId().getDatabase().equals(dbId)) { - foundDb = true; + public void testDatabaseOperations() throws Exception { + final String databaseId = testHelper.getUniqueDatabaseId(); + final String instanceId = testHelper.getInstanceId().getInstance(); + final String createTableT = "CREATE TABLE T (\n" + " K STRING(MAX),\n" + ") PRIMARY KEY(K)"; + + final Database createdDatabase = + dbAdminClient + .createDatabase(instanceId, databaseId, ImmutableList.of(createTableT)) + .get(5, TimeUnit.MINUTES); + dbs.add(createdDatabase); + + assertEquals(databaseId, createdDatabase.getId().getDatabase()); + assertEquals(Dialect.GOOGLE_STANDARD_SQL, createdDatabase.getDialect()); + + final Database retrievedDatabase = dbAdminClient.getDatabase(instanceId, databaseId); + assertEquals(databaseId, retrievedDatabase.getId().getDatabase()); + assertEquals(Dialect.GOOGLE_STANDARD_SQL, retrievedDatabase.getDialect()); + + Optional maybeDatabaseInList = Optional.empty(); + for (Database listedDatabase : dbAdminClient.listDatabases(instanceId).iterateAll()) { + if (listedDatabase.getId().getDatabase().equals(databaseId)) { + maybeDatabaseInList = Optional.of(listedDatabase); break; } } - assertThat(foundDb).isTrue(); + assertTrue("Expected to find database in list", maybeDatabaseInList.isPresent()); + assertEquals(databaseId, maybeDatabaseInList.get().getId().getDatabase()); + assertEquals(Dialect.GOOGLE_STANDARD_SQL, maybeDatabaseInList.get().getDialect()); - String statement2 = "CREATE TABLE T2 (\n" + " K2 STRING(MAX),\n" + ") PRIMARY KEY(K2)"; - OperationFuture op2 = - dbAdminClient.updateDatabaseDdl(instanceId, dbId, ImmutableList.of(statement2), null); - op2.get(TIMEOUT_MINUTES, TimeUnit.MINUTES); - List statementsInDb = dbAdminClient.getDatabaseDdl(instanceId, dbId); - assertThat(statementsInDb).containsExactly(statement1, statement2); + final String createTableT2 = + "CREATE TABLE T2 (\n" + " K2 STRING(MAX),\n" + ") PRIMARY KEY(K2)"; + dbAdminClient + .updateDatabaseDdl(instanceId, databaseId, ImmutableList.of(createTableT2), null) + .get(5, TimeUnit.MINUTES); - dbAdminClient.dropDatabase(instanceId, dbId); + final List databaseDdl = dbAdminClient.getDatabaseDdl(instanceId, databaseId); + assertEquals(databaseDdl, ImmutableList.of(createTableT, createTableT2)); + + dbAdminClient.dropDatabase(instanceId, databaseId); dbs.clear(); + try { - dbAdminClient.getDatabase(testHelper.getInstanceId().getInstance(), dbId); + dbAdminClient.getDatabase(instanceId, databaseId); fail("Expected exception"); - } catch (SpannerException ex) { - assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); + } catch (SpannerException e) { + assertEquals(ErrorCode.NOT_FOUND, e.getErrorCode()); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITLargeReadTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITLargeReadTest.java index 3fa99c225f3..b60505c873a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITLargeReadTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITLargeReadTest.java @@ -16,11 +16,13 @@ package com.google.cloud.spanner.it; +import static com.google.cloud.spanner.testing.EmulatorSpannerHelper.isUsingEmulator; import static com.google.common.truth.Truth.assertThat; import com.google.cloud.ByteArray; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.IntegrationTestEnv; import com.google.cloud.spanner.KeySet; import com.google.cloud.spanner.Mutation; @@ -28,6 +30,7 @@ import com.google.cloud.spanner.ParallelIntegrationTest; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.connection.ConnectionOptions; import com.google.common.hash.HashFunction; import com.google.common.hash.Hashing; import java.util.ArrayList; @@ -35,19 +38,20 @@ import java.util.Collections; import java.util.List; import java.util.Random; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; /** * Integration test reading large amounts of data. The size of data ensures that multiple chunks are * returned by the server. */ @Category(ParallelIntegrationTest.class) -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public class ITLargeReadTest { private static int numRows; @@ -56,9 +60,9 @@ public class ITLargeReadTest { @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); - private static Database db; + private static DatabaseClient googleStandardSQLClient; + private static DatabaseClient postgreSQLClient; private static HashFunction hasher; - private static DatabaseClient client; // Generate a combination of small and large row sizes to allow multiple read/query restarts and // to exercise chunking. @@ -74,7 +78,7 @@ private static List rowSizes() { @BeforeClass public static void setUpDatabase() { - db = + Database googleStandardSQLDatabase = env.getTestHelper() .createTestDatabase( "CREATE TABLE TestTable (" @@ -83,8 +87,22 @@ public static void setUpDatabase() { + " Fingerprint INT64," + " Size INT64," + ") PRIMARY KEY (Key)"); + googleStandardSQLClient = env.getTestHelper().getDatabaseClient(googleStandardSQLDatabase); + if (!isUsingEmulator()) { + Database postgreSQLDatabase = + env.getTestHelper() + .createTestDatabase( + Dialect.POSTGRESQL, + Arrays.asList( + "CREATE TABLE TestTable (" + + " Key BIGINT PRIMARY KEY," + + " Data BYTEA," + + " Fingerprint BIGINT," + + " Size BIGINT" + + ")")); + postgreSQLClient = env.getTestHelper().getDatabaseClient(postgreSQLDatabase); + } hasher = Hashing.goodFastHash(64); - client = env.getTestHelper().getDatabaseClient(db); List mutations = new ArrayList<>(); Random rnd = new Random(); @@ -108,18 +126,50 @@ public static void setUpDatabase() { totalSize += rowSize; i++; if (totalSize >= WRITE_BATCH_SIZE) { - client.write(mutations); + googleStandardSQLClient.write(mutations); + if (!isUsingEmulator()) { + postgreSQLClient.write(mutations); + } mutations.clear(); totalSize = 0; } } - client.write(mutations); + googleStandardSQLClient.write(mutations); + if (!isUsingEmulator()) { + postgreSQLClient.write(mutations); + } + } + + @AfterClass + public static void teardown() { + ConnectionOptions.closeSpanner(); + } + + @Parameterized.Parameters(name = "Dialect = {0}") + public static List data() { + List params = new ArrayList<>(); + params.add(new DialectTestParameter(Dialect.GOOGLE_STANDARD_SQL)); + // "PG dialect tests are not supported by the emulator" + if (!isUsingEmulator()) { + params.add(new DialectTestParameter(Dialect.POSTGRESQL)); + } + return params; + } + + @Parameterized.Parameter(0) + public DialectTestParameter dialect; + + private DatabaseClient getClient(Dialect dialect) { + if (dialect == Dialect.POSTGRESQL) { + return postgreSQLClient; + } + return googleStandardSQLClient; } @Test public void read() { try (ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse() .read(TABLE_NAME, KeySet.all(), Arrays.asList("Key", "Data", "Fingerprint", "Size"))) { validate(resultSet); @@ -129,7 +179,7 @@ public void read() { @Test public void readWithSmallPrefetchChunks() { try (ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse() .read( TABLE_NAME, @@ -143,7 +193,7 @@ public void readWithSmallPrefetchChunks() { @Test public void query() { try (ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse() .executeQuery( Statement.of( @@ -155,7 +205,7 @@ public void query() { @Test public void queryWithSmallPrefetchChunks() { try (ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse() .executeQuery( Statement.of( diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITPgNumericTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITPgNumericTest.java new file mode 100644 index 00000000000..b5fc084a54c --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITPgNumericTest.java @@ -0,0 +1,472 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner.it; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; + +import com.google.cloud.spanner.Database; +import com.google.cloud.spanner.DatabaseAdminClient; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Dialect; +import com.google.cloud.spanner.IntegrationTestEnv; +import com.google.cloud.spanner.Mutation; +import com.google.cloud.spanner.ParallelIntegrationTest; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.Value; +import com.google.cloud.spanner.testing.EmulatorSpannerHelper; +import com.google.cloud.spanner.testing.RemoteSpannerHelper; +import com.google.common.collect.ImmutableList; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.threeten.bp.Duration; + +@Category(ParallelIntegrationTest.class) +@RunWith(JUnit4.class) +public class ITPgNumericTest { + + private static final Duration OPERATION_TIMEOUT = Duration.ofMinutes(5); + + @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); + private static RemoteSpannerHelper testHelper; + private static DatabaseAdminClient databaseAdminClient; + private static List databasesToDrop; + private static String projectId; + private static String instanceId; + private static String databaseId; + private DatabaseClient databaseClient; + private String tableName; + + @BeforeClass + public static void beforeClass() throws Exception { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + testHelper = env.getTestHelper(); + databaseAdminClient = testHelper.getClient().getDatabaseAdminClient(); + databasesToDrop = new ArrayList<>(); + projectId = testHelper.getInstanceId().getProject(); + instanceId = testHelper.getInstanceId().getInstance(); + databaseId = testHelper.getUniqueDatabaseId(); + final Database database = + databaseAdminClient + .newDatabaseBuilder(DatabaseId.of(projectId, instanceId, databaseId)) + .setDialect(Dialect.POSTGRESQL) + .build(); + databaseAdminClient + .createDatabase(database, Collections.emptyList()) + .get(OPERATION_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); + databasesToDrop.add(database.getId()); + } + + @AfterClass + public static void afterClass() throws Exception { + if (databasesToDrop != null) { + for (DatabaseId id : databasesToDrop) { + try { + databaseAdminClient.dropDatabase(id.getInstanceId().getInstance(), id.getDatabase()); + } catch (Exception e) { + System.err.println("Failed to drop database " + id + ", skipping...: " + e.getMessage()); + } + } + } + } + + @Before + public void setUp() throws Exception { + databaseClient = + testHelper.getClient().getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId)); + tableName = testHelper.getUniqueDatabaseId(); + databaseAdminClient + .updateDatabaseDdl( + instanceId, + databaseId, + Collections.singletonList( + "CREATE TABLE \"" + tableName + "\" (id BIGINT PRIMARY KEY, col1 NUMERIC)"), + null) + .get(OPERATION_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); + } + + @Test + public void testLiteralPgNumeric() { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.executeUpdate( + Statement.of( + "INSERT INTO " + + tableName + + " (id, col1) VALUES" + + " (1, 1.23)" + + ", (2, 'NaN')" + + ", (3, null)")); + return null; + }); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + tableName))) { + + resultSet.next(); + assertEquals("1.23", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("1.23"), resultSet.getValue("col1")); + + resultSet.next(); + assertEquals("NaN", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("NaN"), resultSet.getValue("col1")); + + resultSet.next(); + assertTrue(resultSet.isNull("col1")); + } + } + + @Test + public void testParameterizedWithPgNumericAsValue() { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.executeUpdate( + Statement.newBuilder( + "INSERT INTO " + + tableName + + " (id, col1) VALUES" + + " (1, $1)" + + ", (2, $2)" + + ", (3, $3)") + .bind("p1") + .to(Value.pgNumeric("1.23")) + .bind("p2") + .to(Value.pgNumeric("NaN")) + .bind("p3") + .to(Value.pgNumeric(null)) + .build()); + return null; + }); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + tableName))) { + + resultSet.next(); + assertEquals("1.23", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("1.23"), resultSet.getValue("col1")); + + resultSet.next(); + assertEquals("NaN", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("NaN"), resultSet.getValue("col1")); + + resultSet.next(); + assertTrue(resultSet.isNull("col1")); + } + } + + @Test + public void testParameterizedWithPgNumericAsDouble() { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.executeUpdate( + Statement.newBuilder( + "INSERT INTO " + + tableName + + " (id, col1) VALUES" + + " (1, $1)" + + ", (2, $2)" + + ", (3, $3)") + .bind("p1") + .to(1.23D) + .bind("p2") + .to(Double.NaN) + .bind("p3") + .to((Double) null) + .build()); + return null; + }); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + tableName))) { + + resultSet.next(); + assertEquals("1.23", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("1.23"), resultSet.getValue("col1")); + + resultSet.next(); + assertEquals("NaN", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("NaN"), resultSet.getValue("col1")); + + resultSet.next(); + assertTrue(resultSet.isNull("col1")); + } + } + + @Test + public void testParameterizedWithPgNumericAsInt() { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.executeUpdate( + Statement.newBuilder("INSERT INTO " + tableName + " (id, col1) VALUES (1, $1)") + .bind("p1") + .to(1) + .build()); + return null; + }); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + tableName))) { + + resultSet.next(); + assertEquals("1", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("1"), resultSet.getValue("col1")); + } + } + + @Test + public void testParameterizedWithPgNumericAsLong() { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.executeUpdate( + Statement.newBuilder("INSERT INTO " + tableName + " (id, col1) VALUES (1, $1)") + .bind("p1") + .to(1L) + .build()); + return null; + }); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + tableName))) { + + resultSet.next(); + assertEquals("1", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("1"), resultSet.getValue("col1")); + } + } + + @Test + public void testMutationsWithPgNumericAsString() { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.buffer( + ImmutableList.of( + Mutation.newInsertBuilder(tableName) + .set("id") + .to(1) + .set("col1") + .to("1.23") + .build(), + Mutation.newInsertBuilder(tableName) + .set("id") + .to(2) + .set("col1") + .to("NaN") + .build(), + Mutation.newInsertBuilder(tableName) + .set("id") + .to(3) + .set("col1") + .to((String) null) + .build())); + return null; + }); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + tableName))) { + + resultSet.next(); + assertEquals("1.23", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("1.23"), resultSet.getValue("col1")); + + resultSet.next(); + assertEquals("NaN", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("NaN"), resultSet.getValue("col1")); + + resultSet.next(); + assertTrue(resultSet.isNull("col1")); + } + } + + @Test + public void testMutationsWithPgNumericAsInt() { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.buffer( + ImmutableList.of( + Mutation.newInsertBuilder(tableName) + .set("id") + .to(1) + .set("col1") + .to(1) + .build())); + return null; + }); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + tableName))) { + + resultSet.next(); + assertEquals("1", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("1"), resultSet.getValue("col1")); + } + } + + @Test + public void testMutationsWithPgNumericAsLong() { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.buffer( + ImmutableList.of( + Mutation.newInsertBuilder(tableName) + .set("id") + .to(1) + .set("col1") + .to(1L) + .build())); + return null; + }); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + tableName))) { + + resultSet.next(); + assertEquals("1", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("1"), resultSet.getValue("col1")); + } + } + + @Test + public void testMutationsWithPgNumericAsBigDecimal() { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.buffer( + ImmutableList.of( + Mutation.newInsertBuilder(tableName) + .set("id") + .to(1) + .set("col1") + .to(new BigDecimal("1.23")) + .build(), + Mutation.newInsertBuilder(tableName) + .set("id") + .to(3) + .set("col1") + .to((BigDecimal) null) + .build())); + return null; + }); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + tableName))) { + + resultSet.next(); + assertEquals("1.23", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("1.23"), resultSet.getValue("col1")); + + resultSet.next(); + assertTrue(resultSet.isNull("col1")); + } + } + + @Test + public void testMutationsWithPgNumericAsValue() { + assumeFalse( + "PgNumeric is not supported in the emulator", EmulatorSpannerHelper.isUsingEmulator()); + databaseClient + .readWriteTransaction() + .run( + transaction -> { + transaction.buffer( + ImmutableList.of( + Mutation.newInsertBuilder(tableName) + .set("id") + .to(1) + .set("col1") + .to(Value.pgNumeric("1.23")) + .build(), + Mutation.newInsertBuilder(tableName) + .set("id") + .to(2) + .set("col1") + .to(Value.pgNumeric("NaN")) + .build(), + Mutation.newInsertBuilder(tableName) + .set("id") + .to(3) + .set("col1") + .to(Value.pgNumeric(null)) + .build())); + return null; + }); + + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT * FROM " + tableName))) { + + resultSet.next(); + assertEquals("1.23", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("1.23"), resultSet.getValue("col1")); + + resultSet.next(); + assertEquals("NaN", resultSet.getString("col1")); + assertEquals(Value.pgNumeric("NaN"), resultSet.getValue("col1")); + + resultSet.next(); + assertTrue(resultSet.isNull("col1")); + } + } +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java index e0e887624bf..f07bffc2d8f 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITQueryTest.java @@ -30,6 +30,7 @@ import com.google.cloud.Timestamp; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.IntegrationTestEnv; import com.google.cloud.spanner.Mutation; @@ -43,6 +44,7 @@ import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.StructField; import com.google.cloud.spanner.Value; +import com.google.cloud.spanner.connection.ConnectionOptions; import com.google.cloud.spanner.testing.EmulatorSpannerHelper; import com.google.common.base.Joiner; import com.google.common.collect.Iterables; @@ -52,27 +54,69 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; /** Integration tests for query execution. */ @Category(ParallelIntegrationTest.class) -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public class ITQueryTest { @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); - private static Database db; - private static DatabaseClient client; + private static DatabaseClient googleStandardSQLClient; + private static DatabaseClient postgreSQLClient; + private String selectValueQuery; @BeforeClass public static void setUpDatabase() { // Empty database. - db = env.getTestHelper().createTestDatabase(); - client = env.getTestHelper().getDatabaseClient(db); + Database googleStandardSQLDatabase = env.getTestHelper().createTestDatabase(); + googleStandardSQLClient = env.getTestHelper().getDatabaseClient(googleStandardSQLDatabase); + if (!isUsingEmulator()) { + Database postgreSQLDatabase = + env.getTestHelper().createTestDatabase(Dialect.POSTGRESQL, Collections.emptyList()); + postgreSQLClient = env.getTestHelper().getDatabaseClient(postgreSQLDatabase); + } + } + + @AfterClass + public static void teardown() { + ConnectionOptions.closeSpanner(); + } + + @Before + public void initSelectValueQuery() { + selectValueQuery = "SELECT @p1"; + if (dialect.dialect == Dialect.POSTGRESQL) { + selectValueQuery = "SELECT $1"; + } + } + + @Parameterized.Parameters(name = "Dialect = {0}") + public static List data() { + List params = new ArrayList<>(); + params.add(new DialectTestParameter(Dialect.GOOGLE_STANDARD_SQL)); + // "PG dialect tests are not supported by the emulator" + if (!isUsingEmulator()) { + params.add(new DialectTestParameter(Dialect.POSTGRESQL)); + } + return params; + } + + @Parameterized.Parameter(0) + public DialectTestParameter dialect; + + private DatabaseClient getClient(Dialect dialect) { + if (dialect == Dialect.POSTGRESQL) { + return postgreSQLClient; + } + return googleStandardSQLClient; } @Test @@ -88,12 +132,17 @@ public void badQuery() { fail("Expected exception"); } catch (SpannerException ex) { assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); - assertThat(ex.getMessage()).contains("Unrecognized name: Apples"); + if (dialect.dialect == Dialect.POSTGRESQL) { + assertThat(ex.getMessage()).contains("column \"apples\" does not exist"); + } else { + assertThat(ex.getMessage()).contains("Unrecognized name: Apples"); + } } } @Test public void arrayOfStruct() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Type structType = Type.struct(StructField.of("C1", Type.string()), StructField.of("C2", Type.int64())); Struct row = @@ -131,6 +180,7 @@ public void arrayOfStruct() { @Test public void arrayOfStructEmpty() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Type structType = Type.struct(StructField.of("", Type.string()), StructField.of("", Type.int64())); Struct row = @@ -176,7 +226,8 @@ public void arrayOfStructNullElement() { @Test public void bindBool() { - Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to(true).build(), Type.bool()); + Struct row = + execute(Statement.newBuilder(selectValueQuery).bind("p1").to(true).build(), Type.bool()); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBoolean(0)).isEqualTo(true); } @@ -184,26 +235,27 @@ public void bindBool() { @Test public void bindBoolNull() { Struct row = - execute(Statement.newBuilder("SELECT @v").bind("v").to((Boolean) null), Type.bool()); + execute(Statement.newBuilder(selectValueQuery).bind("p1").to((Boolean) null), Type.bool()); assertThat(row.isNull(0)).isTrue(); } @Test public void bindInt64() { - Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to(1234), Type.int64()); + Struct row = execute(Statement.newBuilder(selectValueQuery).bind("p1").to(1234), Type.int64()); assertThat(row.isNull(0)).isFalse(); assertThat(row.getLong(0)).isEqualTo(1234); } @Test public void bindInt64Null() { - Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to((Long) null), Type.int64()); + Struct row = + execute(Statement.newBuilder(selectValueQuery).bind("p1").to((Long) null), Type.int64()); assertThat(row.isNull(0)).isTrue(); } @Test public void bindFloat64() { - Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to(2.0), Type.float64()); + Struct row = execute(Statement.newBuilder(selectValueQuery).bind("p1").to(2.0), Type.float64()); assertThat(row.isNull(0)).isFalse(); assertThat(row.getDouble(0)).isWithin(0.0).of(2.0); } @@ -211,13 +263,15 @@ public void bindFloat64() { @Test public void bindFloat64Null() { Struct row = - execute(Statement.newBuilder("SELECT @v").bind("v").to((Double) null), Type.float64()); + execute( + Statement.newBuilder(selectValueQuery).bind("p1").to((Double) null), Type.float64()); assertThat(row.isNull(0)).isTrue(); } @Test public void bindString() { - Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to("abc"), Type.string()); + Struct row = + execute(Statement.newBuilder(selectValueQuery).bind("p1").to("abc"), Type.string()); assertThat(row.isNull(0)).isFalse(); assertThat(row.getString(0)).isEqualTo("abc"); } @@ -225,17 +279,18 @@ public void bindString() { @Test public void bindStringNull() { Struct row = - execute(Statement.newBuilder("SELECT @v").bind("v").to((String) null), Type.string()); + execute(Statement.newBuilder(selectValueQuery).bind("p1").to((String) null), Type.string()); assertThat(row.isNull(0)).isTrue(); } @Test public void bindJson() { + assumeFalse("JSON are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); Struct row = execute( - Statement.newBuilder("SELECT @v") - .bind("v") + Statement.newBuilder(selectValueQuery) + .bind("p1") .to(Value.json("{\"rating\":9,\"open\":true}")), Type.json()); assertThat(row.isNull(0)).isFalse(); @@ -244,18 +299,22 @@ public void bindJson() { @Test public void bindJsonEmpty() { + assumeFalse("JSON are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); Struct row = - execute(Statement.newBuilder("SELECT @v").bind("v").to(Value.json("{}")), Type.json()); + execute( + Statement.newBuilder(selectValueQuery).bind("p1").to(Value.json("{}")), Type.json()); assertThat(row.isNull(0)).isFalse(); assertThat(row.getJson(0)).isEqualTo("{}"); } @Test public void bindJsonNull() { + assumeFalse("JSON is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); Struct row = - execute(Statement.newBuilder("SELECT @v").bind("v").to(Value.json(null)), Type.json()); + execute( + Statement.newBuilder(selectValueQuery).bind("p1").to(Value.json(null)), Type.json()); assertThat(row.isNull(0)).isTrue(); } @@ -263,7 +322,7 @@ public void bindJsonNull() { public void bindBytes() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").to(ByteArray.copyFrom("xyz")), + Statement.newBuilder(selectValueQuery).bind("p1").to(ByteArray.copyFrom("xyz")), Type.bytes()); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBytes(0)).isEqualTo(ByteArray.copyFrom("xyz")); @@ -272,14 +331,15 @@ public void bindBytes() { @Test public void bindBytesNull() { Struct row = - execute(Statement.newBuilder("SELECT @v").bind("v").to((ByteArray) null), Type.bytes()); + execute( + Statement.newBuilder(selectValueQuery).bind("p1").to((ByteArray) null), Type.bytes()); assertThat(row.isNull(0)).isTrue(); } @Test public void bindTimestamp() { Timestamp t = Timestamp.parseTimestamp("2016-09-18T00:00:00Z"); - Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to(t), Type.timestamp()); + Struct row = execute(Statement.newBuilder(selectValueQuery).bind("p1").to(t), Type.timestamp()); assertThat(row.isNull(0)).isFalse(); assertThat(row.getTimestamp(0)).isEqualTo(t); } @@ -287,21 +347,26 @@ public void bindTimestamp() { @Test public void bindTimestampNull() { Struct row = - execute(Statement.newBuilder("SELECT @v").bind("v").to((Timestamp) null), Type.timestamp()); + execute( + Statement.newBuilder(selectValueQuery).bind("p1").to((Timestamp) null), + Type.timestamp()); assertThat(row.isNull(0)).isTrue(); } @Test public void bindDate() { + assumeFalse("date type is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Date d = Date.parseDate("2016-09-18"); - Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to(d), Type.date()); + Struct row = execute(Statement.newBuilder(selectValueQuery).bind("p1").to(d), Type.date()); assertThat(row.isNull(0)).isFalse(); assertThat(row.getDate(0)).isEqualTo(d); } @Test public void bindDateNull() { - Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to((Date) null), Type.date()); + assumeFalse("date type is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); + Struct row = + execute(Statement.newBuilder(selectValueQuery).bind("p1").to((Date) null), Type.date()); assertThat(row.isNull(0)).isTrue(); } @@ -309,16 +374,39 @@ public void bindDateNull() { public void bindNumeric() { assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); BigDecimal b = new BigDecimal("1.1"); - Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to(b), Type.numeric()); + Statement.Builder statement = Statement.newBuilder(selectValueQuery); + Type expectedType = Type.numeric(); + Object expectedValue = b; + if (dialect.dialect == Dialect.POSTGRESQL) { + expectedType = Type.pgNumeric(); + expectedValue = Value.pgNumeric(b.toString()); + statement.bind("p1").to(Value.pgNumeric(b.toString())); + } else { + statement.bind("p1").to(b); + } + Struct row = execute(statement, expectedType); assertThat(row.isNull(0)).isFalse(); - assertThat(row.getBigDecimal(0)).isEqualTo(b); + Object got; + if (dialect.dialect == Dialect.POSTGRESQL) { + got = row.getValue(0); + } else { + got = row.getBigDecimal(0); + } + assertThat(got).isEqualTo(expectedValue); } @Test public void bindNumericNull() { assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); - Struct row = - execute(Statement.newBuilder("SELECT @v").bind("v").to((BigDecimal) null), Type.numeric()); + Statement.Builder statement = Statement.newBuilder(selectValueQuery); + Type expectedType = Type.numeric(); + if (dialect.dialect == Dialect.POSTGRESQL) { + expectedType = Type.pgNumeric(); + statement.bind("p1").to(Value.pgNumeric(null)); + } else { + statement.bind("p1").to((BigDecimal) null); + } + Struct row = execute(statement, expectedType); assertThat(row.isNull(0)).isTrue(); } @@ -326,18 +414,37 @@ public void bindNumericNull() { public void bindNumeric_doesNotPreservePrecision() { assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); BigDecimal b = new BigDecimal("1.10"); - Struct row = execute(Statement.newBuilder("SELECT @v").bind("v").to(b), Type.numeric()); - assertThat(row.isNull(0)).isFalse(); + Statement.Builder statement = Statement.newBuilder(selectValueQuery); + Type expectedType = Type.numeric(); // Cloud Spanner does not store precision, and will therefore return 1.10 as 1.1. - assertThat(row.getBigDecimal(0)).isNotEqualTo(b); - assertThat(row.getBigDecimal(0)).isEqualTo(b.stripTrailingZeros()); + Object expectedValue = b.stripTrailingZeros(); + if (dialect.dialect == Dialect.POSTGRESQL) { + expectedType = Type.pgNumeric(); + // Cloud Spanner with PG dialect store precision, and will therefore return 1.10. + expectedValue = Value.pgNumeric(b.toString()); + statement.bind("p1").to(Value.pgNumeric(b.toString())); + } else { + statement.bind("p1").to(b); + } + Struct row = execute(statement, expectedType); + assertThat(row.isNull(0)).isFalse(); + Object got; + if (dialect.dialect == Dialect.POSTGRESQL) { + got = row.getValue(0); + } else { + got = row.getBigDecimal(0); + } + assertThat(got).isNotEqualTo(b); + assertThat(got).isEqualTo(expectedValue); } @Test public void bindBoolArray() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toBoolArray(asList(true, null, false)), + Statement.newBuilder(selectValueQuery) + .bind("p1") + .toBoolArray(asList(true, null, false)), Type.array(Type.bool())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBooleanList(0)).containsExactly(true, null, false).inOrder(); @@ -347,7 +454,7 @@ public void bindBoolArray() { public void bindBoolArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toBoolArray(Collections.emptyList()), + Statement.newBuilder(selectValueQuery).bind("p1").toBoolArray(Collections.emptyList()), Type.array(Type.bool())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBooleanList(0)).containsExactly(); @@ -357,7 +464,7 @@ public void bindBoolArrayEmpty() { public void bindBoolArrayNull() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toBoolArray((boolean[]) null), + Statement.newBuilder(selectValueQuery).bind("p1").toBoolArray((boolean[]) null), Type.array(Type.bool())); assertThat(row.isNull(0)).isTrue(); } @@ -366,7 +473,7 @@ public void bindBoolArrayNull() { public void bindInt64Array() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toInt64Array(asList(null, 1L, 2L)), + Statement.newBuilder(selectValueQuery).bind("p1").toInt64Array(asList(null, 1L, 2L)), Type.array(Type.int64())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getLongList(0)).containsExactly(null, 1L, 2L).inOrder(); @@ -376,7 +483,7 @@ public void bindInt64Array() { public void bindInt64ArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toInt64Array(Collections.emptyList()), + Statement.newBuilder(selectValueQuery).bind("p1").toInt64Array(Collections.emptyList()), Type.array(Type.int64())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getLongList(0)).containsExactly(); @@ -386,7 +493,7 @@ public void bindInt64ArrayEmpty() { public void bindInt64ArrayNull() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toInt64Array((long[]) null), + Statement.newBuilder(selectValueQuery).bind("p1").toInt64Array((long[]) null), Type.array(Type.int64())); assertThat(row.isNull(0)).isTrue(); } @@ -395,8 +502,8 @@ public void bindInt64ArrayNull() { public void bindFloat64Array() { Struct row = execute( - Statement.newBuilder("SELECT @v") - .bind("v") + Statement.newBuilder(selectValueQuery) + .bind("p1") .toFloat64Array( asList( null, @@ -417,7 +524,9 @@ public void bindFloat64Array() { public void bindFloat64ArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toFloat64Array(Collections.emptyList()), + Statement.newBuilder(selectValueQuery) + .bind("p1") + .toFloat64Array(Collections.emptyList()), Type.array(Type.float64())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getDoubleList(0)).containsExactly(); @@ -427,7 +536,7 @@ public void bindFloat64ArrayEmpty() { public void bindFloat64ArrayNull() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toFloat64Array((double[]) null), + Statement.newBuilder(selectValueQuery).bind("p1").toFloat64Array((double[]) null), Type.array(Type.float64())); assertThat(row.isNull(0)).isTrue(); } @@ -436,7 +545,7 @@ public void bindFloat64ArrayNull() { public void bindStringArray() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toStringArray(asList("a", "b", null)), + Statement.newBuilder(selectValueQuery).bind("p1").toStringArray(asList("a", "b", null)), Type.array(Type.string())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getStringList(0)).containsExactly("a", "b", null).inOrder(); @@ -446,7 +555,9 @@ public void bindStringArray() { public void bindStringArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toStringArray(Collections.emptyList()), + Statement.newBuilder(selectValueQuery) + .bind("p1") + .toStringArray(Collections.emptyList()), Type.array(Type.string())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getStringList(0)).containsExactly(); @@ -456,18 +567,20 @@ public void bindStringArrayEmpty() { public void bindStringArrayNull() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toStringArray(null), + Statement.newBuilder(selectValueQuery).bind("p1").toStringArray(null), Type.array(Type.string())); assertThat(row.isNull(0)).isTrue(); } @Test public void bindJsonArray() { + assumeFalse( + "array JSON binding is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); Struct row = execute( - Statement.newBuilder("SELECT @v") - .bind("v") + Statement.newBuilder(selectValueQuery) + .bind("p1") .toJsonArray(asList("{}", "[]", "{\"rating\":9,\"open\":true}", null)), Type.array(Type.json())); assertThat(row.isNull(0)).isFalse(); @@ -478,10 +591,11 @@ public void bindJsonArray() { @Test public void bindJsonArrayEmpty() { + assumeFalse("JSON is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toJsonArray(Collections.emptyList()), + Statement.newBuilder(selectValueQuery).bind("p1").toJsonArray(Collections.emptyList()), Type.array(Type.json())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getJsonList(0)).isEqualTo(Collections.emptyList()); @@ -489,10 +603,12 @@ public void bindJsonArrayEmpty() { @Test public void bindJsonArrayNull() { + assumeFalse("JSON is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toJsonArray(null), Type.array(Type.json())); + Statement.newBuilder(selectValueQuery).bind("p1").toJsonArray(null), + Type.array(Type.json())); assertThat(row.isNull(0)).isTrue(); } @@ -503,7 +619,7 @@ public void bindBytesArray() { ByteArray e3 = null; Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toBytesArray(asList(e1, e2, e3)), + Statement.newBuilder(selectValueQuery).bind("p1").toBytesArray(asList(e1, e2, e3)), Type.array(Type.bytes())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBytesList(0)).containsExactly(e1, e2, e3).inOrder(); @@ -513,7 +629,7 @@ public void bindBytesArray() { public void bindBytesArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toBytesArray(Collections.emptyList()), + Statement.newBuilder(selectValueQuery).bind("p1").toBytesArray(Collections.emptyList()), Type.array(Type.bytes())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBytesList(0)).isEmpty(); @@ -523,7 +639,7 @@ public void bindBytesArrayEmpty() { public void bindBytesArrayNull() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toBytesArray(null), + Statement.newBuilder(selectValueQuery).bind("p1").toBytesArray(null), Type.array(Type.bytes())); assertThat(row.isNull(0)).isTrue(); } @@ -535,7 +651,9 @@ public void bindTimestampArray() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toTimestampArray(asList(t1, t2, null)), + Statement.newBuilder(selectValueQuery) + .bind("p1") + .toTimestampArray(asList(t1, t2, null)), Type.array(Type.timestamp())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getTimestampList(0)).containsExactly(t1, t2, null).inOrder(); @@ -545,7 +663,9 @@ public void bindTimestampArray() { public void bindTimestampArrayEmpty() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toTimestampArray(Collections.emptyList()), + Statement.newBuilder(selectValueQuery) + .bind("p1") + .toTimestampArray(Collections.emptyList()), Type.array(Type.timestamp())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getTimestampList(0)).containsExactly(); @@ -555,13 +675,14 @@ public void bindTimestampArrayEmpty() { public void bindTimestampArrayNull() { Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toTimestampArray(null), + Statement.newBuilder(selectValueQuery).bind("p1").toTimestampArray(null), Type.array(Type.timestamp())); assertThat(row.isNull(0)).isTrue(); } @Test public void bindDateArray() { + assumeFalse("date type is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Date d1 = Date.parseDate("2016-09-18"); Date d2 = Date.parseDate("2016-09-19"); @@ -575,6 +696,7 @@ public void bindDateArray() { @Test public void bindDateArrayEmpty() { + assumeFalse("date type is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct row = execute( Statement.newBuilder("SELECT @v").bind("v").toDateArray(Collections.emptyList()), @@ -585,6 +707,7 @@ public void bindDateArrayEmpty() { @Test public void bindDateArrayNull() { + assumeFalse("date type is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct row = execute( Statement.newBuilder("SELECT @v").bind("v").toDateArray(null), Type.array(Type.date())); @@ -593,13 +716,16 @@ public void bindDateArrayNull() { @Test public void bindNumericArray() { + assumeFalse( + "array numeric binding is not supported on POSTGRESQL", + dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); BigDecimal b1 = new BigDecimal("3.14"); BigDecimal b2 = new BigDecimal("6.626"); Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toNumericArray(asList(b1, b2, null)), + Statement.newBuilder(selectValueQuery).bind("p1").toNumericArray(asList(b1, b2, null)), Type.array(Type.numeric())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBigDecimalList(0)).containsExactly(b1, b2, null).inOrder(); @@ -607,10 +733,15 @@ public void bindNumericArray() { @Test public void bindNumericArrayEmpty() { + assumeFalse( + "array numeric binding is not supported on POSTGRESQL", + dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toNumericArray(Collections.emptyList()), + Statement.newBuilder(selectValueQuery) + .bind("p1") + .toNumericArray(Collections.emptyList()), Type.array(Type.numeric())); assertThat(row.isNull(0)).isFalse(); assertThat(row.getBigDecimalList(0)).containsExactly(); @@ -618,16 +749,22 @@ public void bindNumericArrayEmpty() { @Test public void bindNumericArrayNull() { + assumeFalse( + "array numeric binding is not supported on POSTGRESQL", + dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); Struct row = execute( - Statement.newBuilder("SELECT @v").bind("v").toNumericArray(null), + Statement.newBuilder(selectValueQuery).bind("p1").toNumericArray(null), Type.array(Type.numeric())); assertThat(row.isNull(0)).isTrue(); } @Test public void bindNumericArray_doesNotPreservePrecision() { + assumeFalse( + "array numeric binding is not supported on POSTGRESQL", + dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); BigDecimal b1 = new BigDecimal("3.14"); BigDecimal b2 = new BigDecimal("6.626070"); @@ -644,10 +781,11 @@ public void bindNumericArray_doesNotPreservePrecision() { @Test public void unsupportedSelectStructValue() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("The emulator accepts this query", isUsingEmulator()); Struct p = structValue(); try { - execute(Statement.newBuilder("SELECT @p").bind("p").to(p).build(), p.getType()); + execute(Statement.newBuilder(selectValueQuery).bind("p1").to(p).build(), p.getType()); fail("Expected exception"); } catch (SpannerException ex) { assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.UNIMPLEMENTED); @@ -659,6 +797,7 @@ public void unsupportedSelectStructValue() { @Test public void unsupportedSelectArrayStructValue() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); assumeFalse( "Emulator evaluates this expression differently than Cloud Spanner", isUsingEmulator()); @@ -683,6 +822,7 @@ public void unsupportedSelectArrayStructValue() { @Test public void invalidAmbiguousFieldAccess() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct p = Struct.newBuilder().set("f1").to(20).set("f1").to("abc").build(); try { execute(Statement.newBuilder("SELECT @p.f1").bind("p").to(p).build(), Type.int64()); @@ -714,6 +854,7 @@ private Struct structValue() { @Test public void bindStruct() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct p = structValue(); String query = "SELECT " @@ -732,6 +873,7 @@ public void bindStruct() { @Test public void bindArrayOfStruct() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct arrayElement = structValue(); List p = asList(arrayElement, null); @@ -756,6 +898,7 @@ public void bindArrayOfStruct() { @Test public void bindStructNull() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct row = execute( Statement.newBuilder("SELECT @p IS NULL") @@ -773,6 +916,7 @@ public void bindStructNull() { @Test public void bindArrayOfStructNull() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Type elementType = Type.struct( asList( @@ -791,6 +935,7 @@ public void bindArrayOfStructNull() { @Test public void bindEmptyStruct() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct p = Struct.newBuilder().build(); Struct row = execute(Statement.newBuilder("SELECT @p IS NULL").bind("p").to(p).build(), Type.bool()); @@ -799,6 +944,7 @@ public void bindEmptyStruct() { @Test public void bindStructWithUnnamedFields() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct p = Struct.newBuilder().add(Value.int64(1337)).add(Value.int64(7331)).build(); Struct row = executeWithRowResultType( @@ -810,6 +956,7 @@ public void bindStructWithUnnamedFields() { @Test public void bindStructWithDuplicateFieldNames() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct p = Struct.newBuilder() .set("f1") @@ -827,6 +974,7 @@ public void bindStructWithDuplicateFieldNames() { @Test public void bindEmptyArrayOfStruct() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Type elementType = Type.struct(Collections.singletonList(StructField.of("f1", Type.date()))); List p = Collections.emptyList(); assertThat(p).isEmpty(); @@ -843,6 +991,7 @@ public void bindEmptyArrayOfStruct() { @Test public void bindStructWithNullStructField() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Type emptyStructType = Type.struct(new ArrayList<>()); Struct p = Struct.newBuilder().set("f1").to(emptyStructType, null).build(); @@ -853,6 +1002,7 @@ public void bindStructWithNullStructField() { @Test public void bindStructWithBoolArrayFieldThatContainsNulls() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct p = Struct.newBuilder() .set("boolArray") @@ -872,6 +1022,7 @@ public void bindStructWithBoolArrayFieldThatContainsNulls() { @Test public void bindStructWithInt64ArrayFieldThatContainsNulls() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct p = Struct.newBuilder() .set("int64Array") @@ -891,6 +1042,7 @@ public void bindStructWithInt64ArrayFieldThatContainsNulls() { @Test public void bindStructWithFloat64ArrayFieldThatContainsNulls() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct p = Struct.newBuilder() .set("float64Array") @@ -910,6 +1062,7 @@ public void bindStructWithFloat64ArrayFieldThatContainsNulls() { @Test public void bindStructWithStructField() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct nestedStruct = Struct.newBuilder().set("ff1").to("abc").build(); Struct p = Struct.newBuilder().set("f1").to(nestedStruct).build(); @@ -922,6 +1075,7 @@ public void bindStructWithStructField() { @Test public void bindStructWithArrayOfStructField() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct arrayElement1 = Struct.newBuilder().set("ff1").to("abc").build(); Struct arrayElement2 = Struct.newBuilder().set("ff1").to("def").build(); Struct p = @@ -940,8 +1094,13 @@ public void bindStructWithArrayOfStructField() { @Test public void unboundParameter() { + String query = "SELECT @v"; + if (dialect.dialect == Dialect.POSTGRESQL) { + query = "SELECT $1"; + } ResultSet resultSet = - Statement.of("SELECT @v").executeQuery(client.singleUse(TimestampBound.strong())); + Statement.of(query) + .executeQuery(getClient(dialect.dialect).singleUse(TimestampBound.strong())); try { resultSet.next(); fail("Expected exception"); @@ -952,24 +1111,32 @@ public void unboundParameter() { @Test public void positiveInfinity() { + assumeFalse( + "function ieee_divide not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct row = execute(Statement.newBuilder("SELECT IEEE_DIVIDE(1, 0)"), Type.float64()); assertThat(row.getDouble(0)).isPositiveInfinity(); } @Test public void negativeInfinity() { + assumeFalse( + "function ieee_divide not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct row = execute(Statement.newBuilder("SELECT IEEE_DIVIDE(-1, 0)"), Type.float64()); assertThat(row.getDouble(0)).isNegativeInfinity(); } @Test public void notANumber() { + assumeFalse( + "function ieee_divide not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct row = execute(Statement.newBuilder("SELECT IEEE_DIVIDE(0, 0)"), Type.float64()); assertThat(row.getDouble(0)).isNaN(); } @Test public void nonNumberArray() { + assumeFalse( + "function ieee_divide not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); Struct row = execute( Statement.newBuilder( @@ -983,6 +1150,8 @@ public void nonNumberArray() { @Test public void largeErrorText() { + assumeFalse( + "regexp_contains is not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); String veryLongString = Joiner.on("").join(Iterables.limit(Iterables.cycle("x"), 8000)); Statement statement = Statement.newBuilder("SELECT REGEXP_CONTAINS(@value, @regexp)") @@ -991,7 +1160,8 @@ public void largeErrorText() { .bind("regexp") .to("(" + veryLongString) .build(); - ResultSet resultSet = statement.executeQuery(client.singleUse(TimestampBound.strong())); + ResultSet resultSet = + statement.executeQuery(getClient(dialect.dialect).singleUse(TimestampBound.strong())); try { resultSet.next(); fail("Expected exception"); @@ -1003,10 +1173,19 @@ public void largeErrorText() { @Test public void queryRealTable() { - Database populatedDb = - env.getTestHelper() - .createTestDatabase( - "CREATE TABLE T ( K STRING(MAX) NOT NULL, V STRING(MAX) ) PRIMARY KEY (K)"); + Database populatedDb; + if (dialect.dialect == Dialect.POSTGRESQL) { + populatedDb = + env.getTestHelper() + .createTestDatabase( + dialect.dialect, + Arrays.asList("CREATE TABLE T ( K VARCHAR PRIMARY KEY, V VARCHAR )")); + } else { + populatedDb = + env.getTestHelper() + .createTestDatabase( + "CREATE TABLE T ( K STRING(MAX) NOT NULL, V STRING(MAX) ) PRIMARY KEY (K)"); + } DatabaseClient client = env.getTestHelper().getDatabaseClient(populatedDb); client.writeAtLeastOnce( asList( @@ -1015,23 +1194,22 @@ public void queryRealTable() { Mutation.newInsertBuilder("T").set("K").to("k3").set("V").to("v3").build(), Mutation.newInsertBuilder("T").set("K").to("k4").set("V").to("v4").build())); + String query = "SELECT k, v FROM T WHERE k >= @p1 AND k < @p2 ORDER BY K ASC"; + if (dialect.dialect == Dialect.POSTGRESQL) { + query = "SELECT k, v FROM T WHERE k >= $1 AND k < $2 ORDER BY K ASC"; + } Statement statement = - Statement.newBuilder("SELECT K, V FROM T WHERE K >= @min AND K < @max ORDER BY K ASC") - .bind("min") - .to("k13") - .bind("max") - .to("k32") - .build(); + Statement.newBuilder(query).bind("p1").to("k13").bind("p2").to("k32").build(); ResultSet resultSet = statement.executeQuery(client.singleUse(TimestampBound.strong())); assertThat(resultSet.next()).isTrue(); assertThat(resultSet.getType()) .isEqualTo( - Type.struct(StructField.of("K", Type.string()), StructField.of("V", Type.string()))); + Type.struct(StructField.of("k", Type.string()), StructField.of("v", Type.string()))); assertThat(resultSet.getString(0)).isEqualTo("k2"); assertThat(resultSet.getString(1)).isEqualTo("v2"); assertThat(resultSet.next()).isTrue(); - assertThat(resultSet.getString("K")).isEqualTo("k3"); - assertThat(resultSet.getString("V")).isEqualTo("v3"); + assertThat(resultSet.getString("k")).isEqualTo("k3"); + assertThat(resultSet.getString("v")).isEqualTo("v3"); assertThat(resultSet.next()).isFalse(); } @@ -1039,11 +1217,12 @@ public void queryRealTable() { public void analyzePlan() { assumeFalse("Emulator does not support Analyze Plan", isUsingEmulator()); - Statement statement = Statement.of("SELECT 1 AS column UNION ALL SELECT 2"); + Statement statement = Statement.of("SELECT 1 AS data UNION ALL SELECT 2"); ResultSet resultSet = - statement.analyzeQuery(client.singleUse(TimestampBound.strong()), QueryAnalyzeMode.PLAN); + statement.analyzeQuery( + getClient(dialect.dialect).singleUse(TimestampBound.strong()), QueryAnalyzeMode.PLAN); assertThat(resultSet.next()).isFalse(); - assertThat(resultSet.getType()).isEqualTo(Type.struct(StructField.of("column", Type.int64()))); + assertThat(resultSet.getType()).isEqualTo(Type.struct(StructField.of("data", Type.int64()))); ResultSetStats receivedStats = resultSet.getStats(); assertThat(receivedStats).isNotNull(); assertThat(receivedStats.hasQueryPlan()).isTrue(); @@ -1054,12 +1233,18 @@ public void analyzePlan() { public void analyzeProfile() { assumeFalse("Emulator does not support Analyze Profile", isUsingEmulator()); - Statement statement = - Statement.of("SELECT 1 AS column UNION ALL SELECT 2 AS column ORDER BY column"); + String query = "SELECT 1 AS data UNION ALL SELECT 2 AS data ORDER BY data"; + if (dialect.dialect == Dialect.POSTGRESQL) { + // "Statements with set operations and ORDER BY are not supported" + query = "SELECT 1 AS data UNION ALL SELECT 2 AS data"; + } + Statement statement = Statement.of(query); ResultSet resultSet = - statement.analyzeQuery(client.singleUse(TimestampBound.strong()), QueryAnalyzeMode.PROFILE); + statement.analyzeQuery( + getClient(dialect.dialect).singleUse(TimestampBound.strong()), + QueryAnalyzeMode.PROFILE); assertThat(resultSet.next()).isTrue(); - assertThat(resultSet.getType()).isEqualTo(Type.struct(StructField.of("column", Type.int64()))); + assertThat(resultSet.getType()).isEqualTo(Type.struct(StructField.of("data", Type.int64()))); assertThat(resultSet.getLong(0)).isEqualTo(1); assertThat(resultSet.next()).isTrue(); assertThat(resultSet.getLong(0)).isEqualTo(2); @@ -1072,8 +1257,9 @@ public void analyzeProfile() { @Test public void testSelectArrayOfStructs() { + assumeFalse("structs are not supported on POSTGRESQL", dialect.dialect == Dialect.POSTGRESQL); try (ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse() .executeQuery( Statement.of( @@ -1102,7 +1288,8 @@ public void testSelectArrayOfStructs() { private List resultRows(Statement statement, Type expectedRowType) { ArrayList results = new ArrayList<>(); - ResultSet resultSet = statement.executeQuery(client.singleUse(TimestampBound.strong())); + ResultSet resultSet = + statement.executeQuery(getClient(dialect.dialect).singleUse(TimestampBound.strong())); while (resultSet.next()) { Struct row = resultSet.getCurrentRowAsStruct(); results.add(row); @@ -1113,7 +1300,8 @@ private List resultRows(Statement statement, Type expectedRowType) { } private Struct executeWithRowResultType(Statement statement, Type expectedRowType) { - ResultSet resultSet = statement.executeQuery(client.singleUse(TimestampBound.strong())); + ResultSet resultSet = + statement.executeQuery(getClient(dialect.dialect).singleUse(TimestampBound.strong())); assertThat(resultSet.next()).isTrue(); assertThat(resultSet.getType()).isEqualTo(expectedRowType); Struct row = resultSet.getCurrentRowAsStruct(); @@ -1123,6 +1311,9 @@ private Struct executeWithRowResultType(Statement statement, Type expectedRowTyp private Struct execute(Statement statement, Type expectedColumnType) { Type rowType = Type.struct(StructField.of("", expectedColumnType)); + if (dialect.dialect == Dialect.POSTGRESQL) { + rowType = Type.struct(StructField.of("?column?", expectedColumnType)); + } return executeWithRowResultType(statement, rowType); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITReadTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITReadTest.java index 5fd4b27fa4e..c28b48c529a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITReadTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITReadTest.java @@ -18,6 +18,7 @@ import static com.google.cloud.spanner.SpannerMatchers.isSpannerException; import static com.google.cloud.spanner.Type.StructField; +import static com.google.cloud.spanner.testing.EmulatorSpannerHelper.isUsingEmulator; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.fail; @@ -25,6 +26,7 @@ import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseClient; import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.IntegrationTestEnv; import com.google.cloud.spanner.Key; @@ -38,6 +40,7 @@ import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.Type; +import com.google.cloud.spanner.connection.ConnectionOptions; import com.google.cloud.spanner.testing.RemoteSpannerHelper; import io.grpc.Context; import java.util.ArrayList; @@ -49,12 +52,13 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.hamcrest.MatcherAssert; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; /** * Integration tests for read and query. @@ -63,7 +67,7 @@ * Spanner types. */ @Category(ParallelIntegrationTest.class) -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public class ITReadTest { @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); private static final String TABLE_NAME = "TestTable"; @@ -72,42 +76,85 @@ public class ITReadTest { private static final List ALL_COLUMNS = Arrays.asList("Key", "StringValue"); private static final Type TABLE_TYPE = Type.struct( - StructField.of("Key", Type.string()), StructField.of("StringValue", Type.string())); + StructField.of("key", Type.string()), StructField.of("stringvalue", Type.string())); - private static Database db; - private static DatabaseClient client; + private static DatabaseClient googleStandardSQLClient; + private static DatabaseClient postgreSQLClient; @BeforeClass public static void setUpDatabase() { - db = + Database googleStandardSQLDatabase = env.getTestHelper() .createTestDatabase( "CREATE TABLE TestTable (" - + " Key STRING(MAX) NOT NULL," - + " StringValue STRING(MAX)," - + ") PRIMARY KEY (Key)", - "CREATE INDEX TestTableByValue ON TestTable(StringValue)", - "CREATE INDEX TestTableByValueDesc ON TestTable(StringValue DESC)"); - client = env.getTestHelper().getDatabaseClient(db); + + " key STRING(MAX) NOT NULL," + + " stringvalue STRING(MAX)," + + ") PRIMARY KEY (key)", + "CREATE INDEX TestTableByValue ON TestTable(stringvalue)", + "CREATE INDEX TestTableByValueDesc ON TestTable(stringvalue DESC)"); + googleStandardSQLClient = env.getTestHelper().getDatabaseClient(googleStandardSQLDatabase); + if (!isUsingEmulator()) { + Database postgreSQLDatabase = + env.getTestHelper() + .createTestDatabase( + Dialect.POSTGRESQL, + Arrays.asList( + "CREATE TABLE TestTable (" + + " Key VARCHAR PRIMARY KEY," + + " StringValue VARCHAR" + + ")", + "CREATE INDEX TestTableByValue ON TestTable(StringValue)", + "CREATE INDEX TestTableByValueDesc ON TestTable(StringValue DESC)")); + postgreSQLClient = env.getTestHelper().getDatabaseClient(postgreSQLDatabase); + } // Includes k0..k14. Note that strings k{10,14} sort between k1 and k2. List mutations = new ArrayList<>(); for (int i = 0; i < 15; ++i) { mutations.add( Mutation.newInsertOrUpdateBuilder(TABLE_NAME) - .set("Key") + .set("key") .to("k" + i) - .set("StringValue") + .set("stringvalue") .to("v" + i) .build()); } - client.write(mutations); + googleStandardSQLClient.write(mutations); + if (!isUsingEmulator()) { + postgreSQLClient.write(mutations); + } + } + + @AfterClass + public static void teardown() { + ConnectionOptions.closeSpanner(); + } + + @Parameterized.Parameters(name = "Dialect = {0}") + public static List data() { + List params = new ArrayList<>(); + params.add(new DialectTestParameter(Dialect.GOOGLE_STANDARD_SQL)); + // "PG dialect tests are not supported by the emulator" + if (!isUsingEmulator()) { + params.add(new DialectTestParameter(Dialect.POSTGRESQL)); + } + return params; + } + + @Parameterized.Parameter(0) + public DialectTestParameter dialect; + + private DatabaseClient getClient(Dialect dialect) { + if (dialect == Dialect.POSTGRESQL) { + return postgreSQLClient; + } + return googleStandardSQLClient; } @Test public void emptyRead() { ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .read( TABLE_NAME, @@ -120,7 +167,7 @@ public void emptyRead() { @Test public void indexEmptyRead() { ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readUsingIndex( TABLE_NAME, @@ -134,19 +181,21 @@ public void indexEmptyRead() { @Test public void pointRead() { Struct row = - client.singleUse(TimestampBound.strong()).readRow(TABLE_NAME, Key.of("k1"), ALL_COLUMNS); + getClient(dialect.dialect) + .singleUse(TimestampBound.strong()) + .readRow(TABLE_NAME, Key.of("k1"), ALL_COLUMNS); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo("k1"); assertThat(row.getString(1)).isEqualTo("v1"); // Ensure that the Struct implementation supports equality properly. assertThat(row) - .isEqualTo(Struct.newBuilder().set("Key").to("k1").set("StringValue").to("v1").build()); + .isEqualTo(Struct.newBuilder().set("key").to("k1").set("stringvalue").to("v1").build()); } @Test public void indexPointRead() { Struct row = - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRowUsingIndex(TABLE_NAME, INDEX_NAME, Key.of("v1"), ALL_COLUMNS); assertThat(row).isNotNull(); @@ -157,14 +206,16 @@ public void indexPointRead() { @Test public void pointReadNotFound() { Struct row = - client.singleUse(TimestampBound.strong()).readRow(TABLE_NAME, Key.of("k999"), ALL_COLUMNS); + getClient(dialect.dialect) + .singleUse(TimestampBound.strong()) + .readRow(TABLE_NAME, Key.of("k999"), ALL_COLUMNS); assertThat(row).isNull(); } @Test public void indexPointReadNotFound() { Struct row = - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRowUsingIndex(TABLE_NAME, INDEX_NAME, Key.of("v999"), ALL_COLUMNS); assertThat(row).isNull(); @@ -262,7 +313,7 @@ public void indexMultiPointRead() { public void rowsAreSnapshots() { List rows = new ArrayList<>(); ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .read( TABLE_NAME, @@ -303,7 +354,9 @@ public void invalidDatabase() { @Test public void tableNotFound() { try { - client.singleUse(TimestampBound.strong()).readRow("BadTableName", Key.of("k1"), ALL_COLUMNS); + getClient(dialect.dialect) + .singleUse(TimestampBound.strong()) + .readRow("BadTableName", Key.of("k1"), ALL_COLUMNS); fail("Expected exception"); } catch (SpannerException ex) { assertThat(ex.getErrorCode()).isEqualTo(ErrorCode.NOT_FOUND); @@ -314,7 +367,7 @@ public void tableNotFound() { @Test public void columnNotFound() { try { - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRow(TABLE_NAME, Key.of("k1"), Arrays.asList("Key", "BadColumnName")); fail("Expected exception"); @@ -329,7 +382,7 @@ public void cursorErrorDeferred() { // Error should be deferred until next(). This gives consistent behavior with respect to // non-blocking implementations (e.g., gRPC). ResultSet resultSet = - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .read("BadTableName", KeySet.singleKey(Key.of("k1")), ALL_COLUMNS); try { @@ -347,7 +400,7 @@ public void cancellation() { Runnable work = context.wrap( () -> { - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRow(TABLE_NAME, Key.of("k1"), ALL_COLUMNS); }); @@ -369,7 +422,7 @@ public void deadline() { Runnable work = context.wrap( () -> { - client + getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readRow(TABLE_NAME, Key.of("k1"), ALL_COLUMNS); }); @@ -401,32 +454,34 @@ private void checkReadRange(Source source, KeySet keySet, long limit, int[] expe case INDEX: resultSet = limit != 0 - ? client + ? getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readUsingIndex( TABLE_NAME, INDEX_NAME, keySet, ALL_COLUMNS, Options.limit(limit)) - : client + : getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readUsingIndex(TABLE_NAME, INDEX_NAME, keySet, ALL_COLUMNS); break; case DESC_INDEX: resultSet = limit != 0 - ? client + ? getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readUsingIndex( TABLE_NAME, DESC_INDEX_NAME, keySet, ALL_COLUMNS, Options.limit(limit)) - : client + : getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .readUsingIndex(TABLE_NAME, DESC_INDEX_NAME, keySet, ALL_COLUMNS); break; case BASE_TABLE: resultSet = limit != 0 - ? client + ? getClient(dialect.dialect) .singleUse(TimestampBound.strong()) .read(TABLE_NAME, keySet, ALL_COLUMNS, Options.limit(limit)) - : client.singleUse(TimestampBound.strong()).read(TABLE_NAME, keySet, ALL_COLUMNS); + : getClient(dialect.dialect) + .singleUse(TimestampBound.strong()) + .read(TABLE_NAME, keySet, ALL_COLUMNS); break; default: throw new IllegalArgumentException("Invalid source"); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java index 0b2f19e99da..64220421bf1 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITResultSetGetValue.java @@ -21,12 +21,14 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; import com.google.cloud.ByteArray; import com.google.cloud.Date; import com.google.cloud.Timestamp; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.IntegrationTestEnv; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.ParallelIntegrationTest; @@ -36,61 +38,114 @@ import com.google.cloud.spanner.Type; import com.google.cloud.spanner.Type.StructField; import com.google.cloud.spanner.Value; -import com.google.cloud.spanner.testing.RemoteSpannerHelper; +import com.google.cloud.spanner.connection.ConnectionOptions; +import com.google.cloud.spanner.testing.EmulatorSpannerHelper; import com.google.common.primitives.Doubles; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import org.junit.AfterClass; +import org.junit.Assume; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; @Category(ParallelIntegrationTest.class) -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public class ITResultSetGetValue { + @Parameterized.Parameters(name = "Dialect = {0}") + public static List data() { + List params = new ArrayList<>(); + params.add(new DialectTestParameter(Dialect.GOOGLE_STANDARD_SQL)); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + params.add(new DialectTestParameter(Dialect.POSTGRESQL)); + } + return params; + } + + @Parameterized.Parameter() public DialectTestParameter dialect; + @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); // For floats / doubles comparison private static final double DELTA = 1e-15; private static final String TABLE_NAME = "TestTable"; - private static DatabaseClient databaseClient; + private static DatabaseClient googleStandardSQLClient; + private static DatabaseClient postgreSQLClient; + private DatabaseClient databaseClient; @BeforeClass - public static void beforeClass() { - final RemoteSpannerHelper testHelper = env.getTestHelper(); - final Database database = - testHelper.createTestDatabase( - "CREATE TABLE " - + TABLE_NAME - + "(" - + "Id INT64 NOT NULL," - + "bool BOOL," - + "int64 INT64," - + "float64 FLOAT64," - + "numeric NUMERIC," - + "string STRING(MAX)," - + "bytes BYTES(MAX)," - + "timestamp TIMESTAMP," - + "date DATE," - + "boolArray ARRAY," - + "int64Array ARRAY," - + "float64Array ARRAY," - + "numericArray ARRAY," - + "stringArray ARRAY," - + "bytesArray ARRAY," - + "timestampArray ARRAY," - + "dateArray ARRAY" - + ") PRIMARY KEY (Id)"); + public static void beforeClass() + throws ExecutionException, InterruptedException, TimeoutException { + Database googleStandardSqlDatabase = + env.getTestHelper() + .createTestDatabase( + "CREATE TABLE " + + TABLE_NAME + + "(" + + "Id INT64 NOT NULL," + + "bool BOOL," + + "int64 INT64," + + "float64 FLOAT64," + + "numeric NUMERIC," + + "string STRING(MAX)," + + "bytes BYTES(MAX)," + + "timestamp TIMESTAMP," + + "date DATE," + + "boolArray ARRAY," + + "int64Array ARRAY," + + "float64Array ARRAY," + + "numericArray ARRAY," + + "stringArray ARRAY," + + "bytesArray ARRAY," + + "timestampArray ARRAY," + + "dateArray ARRAY" + + ") PRIMARY KEY (Id)"); + googleStandardSQLClient = env.getTestHelper().getDatabaseClient(googleStandardSqlDatabase); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + Database postgreSQLDatabase = + env.getTestHelper() + .createTestDatabase( + Dialect.POSTGRESQL, + Collections.singletonList( + "CREATE TABLE " + + TABLE_NAME + + "(" + + "id BIGINT PRIMARY KEY," + + "bool BOOL," + + "int64 BIGINT," + + "float64 DOUBLE PRECISION," + + "numeric NUMERIC," + + "string VARCHAR," + + "bytes BYTEA" + + ")")); + postgreSQLClient = env.getTestHelper().getDatabaseClient(postgreSQLDatabase); + } + } - databaseClient = testHelper.getDatabaseClient(database); + @Before + public void before() { + databaseClient = + dialect.dialect == Dialect.GOOGLE_STANDARD_SQL ? googleStandardSQLClient : postgreSQLClient; + } + + @AfterClass + public static void teardown() { + ConnectionOptions.closeSpanner(); } @Test - public void testReadNonNullValues() { + public void testReadNonNullValuesGoogleStandardSQL() { + Assume.assumeTrue(dialect.dialect == Dialect.GOOGLE_STANDARD_SQL); databaseClient.write( Collections.singletonList( Mutation.newInsertBuilder(TABLE_NAME) @@ -135,7 +190,6 @@ public void testReadNonNullValues() { Arrays.asList( Date.fromYearMonthDay(2021, 2, 3), Date.fromYearMonthDay(2021, 3, 4))) .build())); - try (ResultSet resultSet = databaseClient .singleUse() @@ -181,7 +235,45 @@ public void testReadNonNullValues() { } @Test - public void testReadNullValues() { + public void testReadNonNullValuesPostgreSQL() { + Assume.assumeTrue(dialect.dialect == Dialect.POSTGRESQL); + databaseClient.write( + Collections.singletonList( + Mutation.newInsertBuilder(TABLE_NAME) + .set("id") + .to(1L) + .set("bool") + .to(true) + .set("int64") + .to(10L) + .set("float64") + .to(20D) + .set("numeric") + .to(new BigDecimal("30")) + .set("string") + .to("stringValue") + .set("bytes") + .to(ByteArray.copyFrom("bytesValue")) + .build())); + + try (ResultSet resultSet = + databaseClient + .singleUse() + .executeQuery(Statement.of("SELECT * FROM " + TABLE_NAME + " WHERE id = 1"))) { + resultSet.next(); + assertEquals(Value.int64(1L), resultSet.getValue("id")); + assertEquals(Value.bool(true), resultSet.getValue("bool")); + assertEquals(Value.int64(10L), resultSet.getValue("int64")); + assertEquals(20D, resultSet.getValue("float64").getFloat64(), 1e-15); + assertEquals(Value.pgNumeric("30"), resultSet.getValue("numeric")); + assertEquals(Value.string("stringValue"), resultSet.getValue("string")); + assertEquals(Value.bytes(ByteArray.copyFrom("bytesValue")), resultSet.getValue("bytes")); + } + } + + @Test + public void testReadNullValuesGoogleStandardSQL() { + Assume.assumeTrue(dialect.dialect == Dialect.GOOGLE_STANDARD_SQL); databaseClient.write( Collections.singletonList(Mutation.newInsertBuilder(TABLE_NAME).set("Id").to(2L).build())); try (ResultSet resultSet = @@ -236,8 +328,36 @@ public void testReadNullValues() { } } + @Test + public void testReadNullValuesPostgreSQL() { + Assume.assumeTrue(dialect.dialect == Dialect.POSTGRESQL); + databaseClient.write( + Collections.singletonList(Mutation.newInsertBuilder(TABLE_NAME).set("id").to(2L).build())); + try (ResultSet resultSet = + databaseClient + .singleUse() + .executeQuery(Statement.of("SELECT * FROM " + TABLE_NAME + " WHERE id = 2"))) { + resultSet.next(); + + assertEquals(Value.int64(2L), resultSet.getValue("id")); + assertTrue(resultSet.getValue("bool").isNull()); + assertThrows(IllegalStateException.class, () -> resultSet.getValue("bool").getBool()); + assertTrue(resultSet.getValue("int64").isNull()); + assertThrows(IllegalStateException.class, () -> resultSet.getValue("int64").getInt64()); + assertTrue(resultSet.getValue("float64").isNull()); + assertThrows(IllegalStateException.class, () -> resultSet.getValue("float64").getFloat64()); + assertTrue(resultSet.getValue("numeric").isNull()); + assertThrows(IllegalStateException.class, () -> resultSet.getValue("numeric").getNumeric()); + assertTrue(resultSet.getValue("string").isNull()); + assertThrows(IllegalStateException.class, () -> resultSet.getValue("string").getString()); + assertTrue(resultSet.getValue("bytes").isNull()); + assertThrows(IllegalStateException.class, () -> resultSet.getValue("bytes").getBytes()); + } + } + @Test public void testReadNullValuesInArrays() { + assumeFalse("PostgreSQL does not yet support Arrays", dialect.dialect == Dialect.POSTGRESQL); databaseClient.write( Collections.singletonList( Mutation.newInsertBuilder(TABLE_NAME) @@ -290,7 +410,8 @@ public void testReadNullValuesInArrays() { } @Test - public void testReadNonFloat64Literals() { + public void testReadNonFloat64LiteralsGoogleStandardSQL() { + Assume.assumeTrue(dialect.dialect == Dialect.GOOGLE_STANDARD_SQL); try (ResultSet resultSet = databaseClient .singleUse() @@ -417,7 +538,32 @@ public void testReadNonFloat64Literals() { } @Test - public void testReadFloat64Literals() { + public void testReadNonFloat64LiteralsPostgreSQL() { + Assume.assumeTrue(dialect.dialect == Dialect.POSTGRESQL); + try (ResultSet resultSet = + databaseClient + .singleUse() + .executeQuery( + Statement.of( + "SELECT " + + "TRUE AS bool," + + "1 AS int64," + + "CAST('100' AS numeric) AS numeric," + + "'stringValue' AS string," + + "CAST('bytesValue' AS BYTEA) AS bytes"))) { + resultSet.next(); + + assertEquals(Value.bool(true), resultSet.getValue("bool")); + assertEquals(Value.int64(1L), resultSet.getValue("int64")); + assertEquals(Value.pgNumeric("100"), resultSet.getValue("numeric")); + assertEquals(Value.string("stringValue"), resultSet.getValue("string")); + assertEquals(Value.bytes(ByteArray.copyFrom("bytesValue")), resultSet.getValue("bytes")); + } + } + + @Test + public void testReadFloat64LiteralsGoogleStandardSQL() { + Assume.assumeTrue(dialect.dialect == Dialect.GOOGLE_STANDARD_SQL); try (ResultSet resultSet = databaseClient .singleUse() @@ -444,4 +590,14 @@ public void testReadFloat64Literals() { new double[] {50D, 60D}, struct.getDoubleArray("structFloat64Array"), DELTA); } } + + @Test + public void testReadFloat64LiteralsPostgreSQL() { + Assume.assumeTrue(dialect.dialect == Dialect.POSTGRESQL); + try (ResultSet resultSet = + databaseClient.singleUse().executeQuery(Statement.of("SELECT 10.0 AS float64"))) { + resultSet.next(); + assertEquals(10D, resultSet.getValue("float64").getFloat64(), DELTA); + } + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerTest.java index bb70864d3c3..736f00ebd69 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITTransactionManagerTest.java @@ -26,6 +26,7 @@ import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.IntegrationTestEnv; import com.google.cloud.spanner.Key; import com.google.cloud.spanner.KeySet; @@ -37,43 +38,84 @@ import com.google.cloud.spanner.TransactionContext; import com.google.cloud.spanner.TransactionManager; import com.google.cloud.spanner.TransactionManager.TransactionState; +import com.google.cloud.spanner.connection.ConnectionOptions; +import com.google.cloud.spanner.testing.EmulatorSpannerHelper; import com.google.common.collect.ImmutableList; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; @Category(ParallelIntegrationTest.class) -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public class ITTransactionManagerTest { @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); - private static Database db; private static DatabaseClient client; + private static DatabaseClient googleStandardSQLClient; + private static DatabaseClient postgreSQLClient; + + @Parameterized.Parameters(name = "Dialect = {0}") + public static List data() { + List params = new ArrayList<>(); + params.add(new DialectTestParameter(Dialect.GOOGLE_STANDARD_SQL)); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + params.add(new DialectTestParameter(Dialect.POSTGRESQL)); + } + return params; + } + + @Parameterized.Parameter() public DialectTestParameter dialect; @BeforeClass - public static void setUpDatabase() { - // Empty database. - db = + public static void setUpDatabase() + throws ExecutionException, InterruptedException, TimeoutException { + + Database googleStandardSQLDatabase = env.getTestHelper() .createTestDatabase( "CREATE TABLE T (" + " K STRING(MAX) NOT NULL," + " BoolValue BOOL," + ") PRIMARY KEY (K)"); - client = env.getTestHelper().getDatabaseClient(db); + googleStandardSQLClient = env.getTestHelper().getDatabaseClient(googleStandardSQLDatabase); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + Database postgreSQLDatabase = + env.getTestHelper() + .createTestDatabase( + Dialect.POSTGRESQL, + Collections.singletonList( + "CREATE TABLE T (" + + " K VARCHAR PRIMARY KEY," + + " BoolValue BOOL" + + ")")); + postgreSQLClient = env.getTestHelper().getDatabaseClient(postgreSQLDatabase); + } } @Before - public void deleteTestData() { + public void before() { + client = + dialect.dialect == Dialect.GOOGLE_STANDARD_SQL ? googleStandardSQLClient : postgreSQLClient; + // Delete all test data client.write(ImmutableList.of(Mutation.delete("T", KeySet.all()))); } + @AfterClass + public static void teardown() { + ConnectionOptions.closeSpanner(); + } + @SuppressWarnings("resource") @Test public void simpleInsert() throws InterruptedException { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java index a76c40ea61b..d274cdb91f5 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITWriteTest.java @@ -32,6 +32,7 @@ import com.google.cloud.spanner.CommitResponse; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.IntegrationTestEnv; import com.google.cloud.spanner.Key; @@ -44,36 +45,57 @@ import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.Value; +import com.google.cloud.spanner.connection.ConnectionOptions; import com.google.cloud.spanner.testing.EmulatorSpannerHelper; import com.google.common.collect.ImmutableList; import io.grpc.Context; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.hamcrest.MatcherAssert; +import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; /** Integration test for writing data to Cloud Spanner. */ @Category(ParallelIntegrationTest.class) -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public class ITWriteTest { @ClassRule public static IntegrationTestEnv env = new IntegrationTestEnv(); + @Parameterized.Parameters(name = "Dialect = {0}") + public static List data() { + List params = new ArrayList<>(); + params.add(new DialectTestParameter(Dialect.GOOGLE_STANDARD_SQL)); + if (!EmulatorSpannerHelper.isUsingEmulator()) { + params.add(new DialectTestParameter(Dialect.POSTGRESQL)); + } + return params; + } + + @Parameterized.Parameter() public DialectTestParameter dialect; + + private static DatabaseClient googleStandardSQLClient; + private static DatabaseClient postgreSQLClient; + // TODO: Remove when the emulator supports NUMERIC and JSON - private static final String SCHEMA_WITH_NUMERIC_AND_JSON = + private static final String GOOGLE_STANDARD_SQL_SCHEMA_WITH_NUMERIC_AND_JSON = "CREATE TABLE T (" + " K STRING(MAX) NOT NULL," + " BoolValue BOOL," @@ -95,7 +117,19 @@ public class ITWriteTest { + " DateArrayValue ARRAY," + " NumericArrayValue ARRAY," + ") PRIMARY KEY (K)"; - private static final String SCHEMA_WITHOUT_NUMERIC_AND_JSON = + + private static final String POSTGRESQL_SCHEMA_WITH_NUMERIC = + "CREATE TABLE T (" + + " K VARCHAR PRIMARY KEY," + + " BoolValue BOOL," + + " Int64Value BIGINT," + + " Float64Value DOUBLE PRECISION," + + " StringValue VARCHAR," + + " BytesValue BYTEA," + + " NumericValue NUMERIC" + + ")"; + + private static final String GOOGLE_STANDARD_SQL_SCHEMA_WITHOUT_NUMERIC_AND_JSON = "CREATE TABLE T (" + " K STRING(MAX) NOT NULL," + " BoolValue BOOL," @@ -114,21 +148,42 @@ public class ITWriteTest { + " DateArrayValue ARRAY," + ") PRIMARY KEY (K)"; - private static Database db; /** Sequence used to generate unique keys. */ private static int seq; private static DatabaseClient client; @BeforeClass - public static void setUpDatabase() { + public static void setUpDatabase() + throws ExecutionException, InterruptedException, TimeoutException { if (EmulatorSpannerHelper.isUsingEmulator()) { - // The emulator does not yet support NUMERIC or JSON. - db = env.getTestHelper().createTestDatabase(SCHEMA_WITHOUT_NUMERIC_AND_JSON); + Database googleStandardSQLDatabase = + env.getTestHelper() + .createTestDatabase(GOOGLE_STANDARD_SQL_SCHEMA_WITHOUT_NUMERIC_AND_JSON); + + googleStandardSQLClient = env.getTestHelper().getDatabaseClient(googleStandardSQLDatabase); } else { - db = env.getTestHelper().createTestDatabase(SCHEMA_WITH_NUMERIC_AND_JSON); + Database googleStandardSQLDatabase = + env.getTestHelper().createTestDatabase(GOOGLE_STANDARD_SQL_SCHEMA_WITH_NUMERIC_AND_JSON); + + googleStandardSQLClient = env.getTestHelper().getDatabaseClient(googleStandardSQLDatabase); + Database postgreSQLDatabase = + env.getTestHelper() + .createTestDatabase( + Dialect.POSTGRESQL, Collections.singletonList(POSTGRESQL_SCHEMA_WITH_NUMERIC)); + postgreSQLClient = env.getTestHelper().getDatabaseClient(postgreSQLDatabase); } - client = env.getTestHelper().getDatabaseClient(db); + } + + @Before + public void before() { + client = + dialect.dialect == Dialect.GOOGLE_STANDARD_SQL ? googleStandardSQLClient : postgreSQLClient; + } + + @AfterClass + public static void teardown() { + ConnectionOptions.closeSpanner(); } private static String uniqueString() { @@ -328,6 +383,7 @@ public void writeStringNull() { @Test public void writeJson() { assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); + assumeFalse("PostgreSQL does not yet support JSON", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("JsonValue").to(Value.json("{\"rating\":9,\"open\":true}")).build()); Struct row = readLastRow("JsonValue"); assertThat(row.isNull(0)).isFalse(); @@ -338,6 +394,7 @@ public void writeJson() { @Test public void writeJsonEmpty() { assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); + assumeFalse("PostgreSQL does not yet support JSON", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("JsonValue").to(Value.json("{}")).build()); Struct row = readLastRow("JsonValue"); assertThat(row.isNull(0)).isFalse(); @@ -348,6 +405,7 @@ public void writeJsonEmpty() { @Test public void writeJsonNull() { assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); + assumeFalse("PostgreSQL does not yet support JSON", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("JsonValue").to(Value.json(null)).build()); Struct row = readLastRow("JsonValue"); assertThat(row.isNull(0)).isTrue(); @@ -423,6 +481,8 @@ public void writeBytesNull() { @Test public void writeTimestamp() { + assumeFalse( + "PostgresSQL does not yet support Timestamp", dialect.dialect == Dialect.POSTGRESQL); Timestamp timestamp = Timestamp.parseTimestamp("2016-09-15T00:00:00.111111Z"); write(baseInsert().set("TimestampValue").to(timestamp).build()); Struct row = readLastRow("TimestampValue"); @@ -432,6 +492,7 @@ public void writeTimestamp() { @Test public void writeTimestampNull() { + assumeFalse("PostgreSQL does not yet support Timestamp", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("TimestampValue").to((Timestamp) null).build()); Struct row = readLastRow("TimestampValue"); assertThat(row.isNull(0)).isTrue(); @@ -439,6 +500,7 @@ public void writeTimestampNull() { @Test public void writeCommitTimestamp() { + assumeFalse("PostgreSQL does not yet support Timestamp", dialect.dialect == Dialect.POSTGRESQL); Timestamp commitTimestamp = write(baseInsert().set("TimestampValue").to(Value.COMMIT_TIMESTAMP).build()); Struct row = readLastRow("TimestampValue"); @@ -447,6 +509,7 @@ public void writeCommitTimestamp() { @Test public void writeDate() { + assumeFalse("PostgreSQL does not yet support Date", dialect.dialect == Dialect.POSTGRESQL); Date date = Date.parseDate("2016-09-15"); write(baseInsert().set("DateValue").to(date).build()); Struct row = readLastRow("DateValue"); @@ -456,6 +519,7 @@ public void writeDate() { @Test public void writeDateNull() { + assumeFalse("PostgreSQL does not yet support Date", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("DateValue").to((Date) null).build()); Struct row = readLastRow("DateValue"); assertThat(row.isNull(0)).isTrue(); @@ -464,22 +528,27 @@ public void writeDateNull() { @Test public void writeNumeric() { assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); - write(baseInsert().set("NumericValue").to(new BigDecimal("3.141592")).build()); + write(baseInsert().set("NumericValue").to("3.141592").build()); Struct row = readLastRow("NumericValue"); assertThat(row.isNull(0)).isFalse(); - assertThat(row.getBigDecimal(0)).isEqualTo(BigDecimal.valueOf(3141592, 6)); + if (dialect.dialect == Dialect.GOOGLE_STANDARD_SQL) { + assertThat(row.getBigDecimal(0)).isEqualTo(BigDecimal.valueOf(3141592, 6)); + } else { + assertThat(row.getString(0)).isEqualTo("3.141592"); + } } @Test public void writeNumericNull() { assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); - write(baseInsert().set("NumericValue").to((Long) null).build()); + write(baseInsert().set("NumericValue").to((String) null).build()); Struct row = readLastRow("NumericValue"); assertThat(row.isNull(0)).isTrue(); } @Test public void writeBoolArrayNull() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("BoolArrayValue").toBoolArray((boolean[]) null).build()); Struct row = readLastRow("BoolArrayValue"); assertThat(row.isNull(0)).isTrue(); @@ -487,6 +556,7 @@ public void writeBoolArrayNull() { @Test public void writeBoolArrayEmpty() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("BoolArrayValue").toBoolArray(new boolean[] {}).build()); Struct row = readLastRow("BoolArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -495,6 +565,7 @@ public void writeBoolArrayEmpty() { @Test public void writeBoolArray() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("BoolArrayValue").toBoolArray(Arrays.asList(true, null, false)).build()); Struct row = readLastRow("BoolArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -509,6 +580,7 @@ public void writeBoolArray() { @Test public void writeBoolArrayNoNulls() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("BoolArrayValue").toBoolArray(Arrays.asList(true, false)).build()); Struct row = readLastRow("BoolArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -517,6 +589,7 @@ public void writeBoolArrayNoNulls() { @Test public void writeInt64ArrayNull() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("Int64ArrayValue").toInt64Array((long[]) null).build()); Struct row = readLastRow("Int64ArrayValue"); assertThat(row.isNull(0)).isTrue(); @@ -524,6 +597,7 @@ public void writeInt64ArrayNull() { @Test public void writeInt64ArrayEmpty() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("Int64ArrayValue").toInt64Array(new long[] {}).build()); Struct row = readLastRow("Int64ArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -532,6 +606,7 @@ public void writeInt64ArrayEmpty() { @Test public void writeInt64Array() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("Int64ArrayValue").toInt64Array(Arrays.asList(1L, 2L, null)).build()); Struct row = readLastRow("Int64ArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -546,6 +621,7 @@ public void writeInt64Array() { @Test public void writeInt64ArrayNoNulls() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("Int64ArrayValue").toInt64Array(Arrays.asList(1L, 2L)).build()); Struct row = readLastRow("Int64ArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -554,6 +630,7 @@ public void writeInt64ArrayNoNulls() { @Test public void writeFloat64ArrayNull() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("Float64ArrayValue").toFloat64Array((double[]) null).build()); Struct row = readLastRow("Float64ArrayValue"); assertThat(row.isNull(0)).isTrue(); @@ -561,6 +638,7 @@ public void writeFloat64ArrayNull() { @Test public void writeFloat64ArrayEmpty() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("Float64ArrayValue").toFloat64Array(new double[] {}).build()); Struct row = readLastRow("Float64ArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -569,6 +647,7 @@ public void writeFloat64ArrayEmpty() { @Test public void writeFloat64Array() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write( baseInsert() .set("Float64ArrayValue") @@ -587,6 +666,7 @@ public void writeFloat64Array() { @Test public void writeFloat64ArrayNoNulls() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("Float64ArrayValue").toFloat64Array(Arrays.asList(1.0, 2.0)).build()); Struct row = readLastRow("Float64ArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -597,6 +677,7 @@ public void writeFloat64ArrayNoNulls() { @Test public void writeStringArrayNull() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("StringArrayValue").toStringArray(null).build()); Struct row = readLastRow("StringArrayValue"); assertThat(row.isNull(0)).isTrue(); @@ -604,6 +685,7 @@ public void writeStringArrayNull() { @Test public void writeStringArrayEmpty() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("StringArrayValue").toStringArray(Collections.emptyList()).build()); Struct row = readLastRow("StringArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -612,6 +694,7 @@ public void writeStringArrayEmpty() { @Test public void writeStringArray() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write( baseInsert().set("StringArrayValue").toStringArray(Arrays.asList("a", null, "b")).build()); Struct row = readLastRow("StringArrayValue"); @@ -621,6 +704,7 @@ public void writeStringArray() { @Test public void writeJsonArrayNull() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); write(baseInsert().set("JsonArrayValue").toJsonArray(null).build()); Struct row = readLastRow("JsonArrayValue"); @@ -630,6 +714,7 @@ public void writeJsonArrayNull() { @Test public void writeJsonArrayEmpty() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); write(baseInsert().set("JsonArrayValue").toJsonArray(Collections.emptyList()).build()); Struct row = readLastRow("JsonArrayValue"); @@ -640,6 +725,7 @@ public void writeJsonArrayEmpty() { @Test public void writeJsonArray() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); write(baseInsert().set("JsonArrayValue").toJsonArray(Arrays.asList("[]", null, "{}")).build()); Struct row = readLastRow("JsonArrayValue"); @@ -650,6 +736,7 @@ public void writeJsonArray() { @Test public void writeJsonArrayNoNulls() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support JSON", EmulatorSpannerHelper.isUsingEmulator()); write( baseInsert() @@ -666,6 +753,7 @@ public void writeJsonArrayNoNulls() { @Test public void writeBytesArrayNull() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("BytesArrayValue").toBytesArray(null).build()); Struct row = readLastRow("BytesArrayValue"); assertThat(row.isNull(0)).isTrue(); @@ -673,6 +761,7 @@ public void writeBytesArrayNull() { @Test public void writeBytesArrayEmpty() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("BytesArrayValue").toBytesArray(Collections.emptyList()).build()); Struct row = readLastRow("BytesArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -681,6 +770,7 @@ public void writeBytesArrayEmpty() { @Test public void writeBytesArray() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); List data = Arrays.asList(ByteArray.copyFrom("a"), ByteArray.copyFrom("b"), null); write(baseInsert().set("BytesArrayValue").toBytesArray(data).build()); Struct row = readLastRow("BytesArrayValue"); @@ -690,6 +780,7 @@ public void writeBytesArray() { @Test public void writeTimestampArrayNull() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("TimestampArrayValue").toTimestampArray(null).build()); Struct row = readLastRow("TimestampArrayValue"); assertThat(row.isNull(0)).isTrue(); @@ -697,6 +788,7 @@ public void writeTimestampArrayNull() { @Test public void writeTimestampArrayEmpty() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write( baseInsert().set("TimestampArrayValue").toTimestampArray(Collections.emptyList()).build()); Struct row = readLastRow("TimestampArrayValue"); @@ -706,6 +798,7 @@ public void writeTimestampArrayEmpty() { @Test public void writeTimestampArray() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); Timestamp t1 = Timestamp.parseTimestamp("2016-09-18T00:00:00Z"); Timestamp t2 = Timestamp.parseTimestamp("2016-09-19T00:00:00Z"); write( @@ -720,6 +813,7 @@ public void writeTimestampArray() { @Test public void writeDateArrayNull() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("DateArrayValue").toDateArray(null).build()); Struct row = readLastRow("DateArrayValue"); assertThat(row.isNull(0)).isTrue(); @@ -727,6 +821,7 @@ public void writeDateArrayNull() { @Test public void writeDateArrayEmpty() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); write(baseInsert().set("DateArrayValue").toDateArray(Collections.emptyList()).build()); Struct row = readLastRow("DateArrayValue"); assertThat(row.isNull(0)).isFalse(); @@ -735,6 +830,7 @@ public void writeDateArrayEmpty() { @Test public void writeDateArray() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); Date d1 = Date.parseDate("2016-09-18"); Date d2 = Date.parseDate("2016-09-19"); write(baseInsert().set("DateArrayValue").toDateArray(Arrays.asList(d1, null, d2)).build()); @@ -745,6 +841,7 @@ public void writeDateArray() { @Test public void writeNumericArrayNull() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); write(baseInsert().set("NumericArrayValue").toNumericArray(null).build()); Struct row = readLastRow("NumericArrayValue"); @@ -753,6 +850,7 @@ public void writeNumericArrayNull() { @Test public void writeNumericArrayEmpty() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); write(baseInsert().set("NumericArrayValue").toNumericArray(ImmutableList.of()).build()); Struct row = readLastRow("NumericArrayValue"); @@ -762,6 +860,7 @@ public void writeNumericArrayEmpty() { @Test public void writeNumericArray() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); write( baseInsert() @@ -778,6 +877,7 @@ public void writeNumericArray() { @Test public void writeNumericArrayNoNulls() { + assumeFalse("PostgreSQL does not yet support Array", dialect.dialect == Dialect.POSTGRESQL); assumeFalse("Emulator does not yet support NUMERIC", EmulatorSpannerHelper.isUsingEmulator()); write( baseInsert() diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/slow/ITBackupTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/slow/ITBackupTest.java index a40a416b4c9..e27909abe89 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/slow/ITBackupTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/slow/ITBackupTest.java @@ -40,6 +40,7 @@ import com.google.cloud.spanner.DatabaseAdminClient; import com.google.cloud.spanner.DatabaseClient; import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.Instance; import com.google.cloud.spanner.InstanceAdminClient; @@ -264,6 +265,8 @@ public void test01_Backups() throws InterruptedException, ExecutionException, Ti // Verifies that the database encryption has been properly set testDatabaseEncryption(database, keyName); + // Verifies that the database dialect has been properly set + testDatabaseDialect(database, Dialect.GOOGLE_STANDARD_SQL); // Create a backup of the database. String backupId = testHelper.getUniqueBackupId() + "_bck1"; @@ -598,6 +601,13 @@ private void testDatabaseEncryption(Database database, String expectedKey) { logger.info("Done verifying database encryption for " + database.getId()); } + private void testDatabaseDialect(Database database, Dialect expectedDialect) { + logger.info("Verifying dialect for " + database.getId()); + assertNotNull(database.getDialect()); + assertEquals(expectedDialect, database.getDialect()); + logger.info("Done verifying database dialect for " + database.getId()); + } + private void testBackupEncryption(Backup backup, String expectedKey) { logger.info("Verifying backup encryption for " + backup.getId()); assertNotNull(backup.getEncryptionInfo()); @@ -813,6 +823,7 @@ private void testRestore(Backup backup, Timestamp versionTime, String expectedKe Timestamp.fromProto( reloadedDatabase.getProto().getRestoreInfo().getBackupInfo().getVersionTime())); testDatabaseEncryption(reloadedDatabase, expectedKey); + testDatabaseDialect(reloadedDatabase, Dialect.GOOGLE_STANDARD_SQL); // Restoring the backup to an existing database should fail. logger.info( diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java index 7c6d6df346c..4ed6c32c7bf 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java @@ -29,6 +29,7 @@ import com.google.auth.oauth2.OAuth2Credentials; import com.google.cloud.spanner.DatabaseClient; import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; import com.google.cloud.spanner.MockSpannerServiceImpl; import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime; @@ -70,14 +71,15 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import org.junit.After; -import org.junit.AfterClass; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; import org.threeten.bp.Duration; -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public class GapicSpannerRpcTest { private static final Statement SELECT1AND2 = @@ -134,8 +136,15 @@ public class GapicSpannerRpcTest { private static String defaultUserAgent; private static Spanner spanner; - @BeforeClass - public static void startServer() throws IOException { + @Parameter public Dialect dialect; + + @Parameters(name = "dialect = {0}") + public static Object[] data() { + return Dialect.values(); + } + + @Before + public void startServer() throws IOException { assumeTrue( "Skip tests when emulator is enabled as this test interferes with the check whether the emulator is running", System.getenv("SPANNER_EMULATOR_HOST") == null); @@ -172,20 +181,20 @@ public ServerCall.Listener interceptCall( spanner = createSpannerOptions().getService(); } - @AfterClass - public static void stopServer() throws InterruptedException { + @After + public void reset() throws InterruptedException { + if (mockSpanner != null) { + mockSpanner.reset(); + } if (spanner != null) { spanner.close(); + } + if (server != null) { server.shutdown(); server.awaitTermination(); } } - @After - public void reset() { - mockSpanner.reset(); - } - @Test public void testCallCredentialsProviderPreferenceAboveCredentials() { SpannerOptions options = @@ -387,10 +396,11 @@ public void testCustomUserAgent() { } } - private static SpannerOptions createSpannerOptions() { + private SpannerOptions createSpannerOptions() { String endpoint = address.getHostString() + ":" + server.getPort(); return SpannerOptions.newBuilder() .setProjectId("[PROJECT]") + .setDialect(dialect) // Set a custom channel configurator to allow http instead of https. .setChannelConfigurator( input -> { diff --git a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/ClientSideStatementsTest.sql b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/ClientSideStatementsTest.sql index 0e87a357c45..4fe25d53b05 100644 --- a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/ClientSideStatementsTest.sql +++ b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/ClientSideStatementsTest.sql @@ -33,169 +33,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#autocommit; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable autocommit; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-autocommit; NEW_CONNECTION; show variable readonly; @@ -232,169 +232,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#readonly; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable readonly; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable readonly/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-readonly; NEW_CONNECTION; set readonly=false; @@ -459,7 +459,7 @@ foo show variable retry_aborts_internally; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally bar; NEW_CONNECTION; set readonly=false; @@ -469,12 +469,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally%; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -484,12 +484,12 @@ _show variable retry_aborts_internally; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally_; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -499,12 +499,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally&; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -514,12 +514,12 @@ $show variable retry_aborts_internally; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally$; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -529,12 +529,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally@; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -544,12 +544,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally!; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -559,12 +559,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally*; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -574,12 +574,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally(; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -589,12 +589,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally); NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -604,12 +604,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally-; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -619,12 +619,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally+; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -634,12 +634,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally-#; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -649,12 +649,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally/; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -664,12 +664,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally\; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -679,12 +679,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally?; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -694,12 +694,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally-/; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -709,12 +709,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally/#; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#retry_aborts_internally; NEW_CONNECTION; set readonly=false; @@ -724,12 +724,12 @@ set autocommit=false; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable retry_aborts_internally/-; NEW_CONNECTION; set readonly=false; set autocommit=false; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-retry_aborts_internally; NEW_CONNECTION; show variable autocommit_dml_mode; @@ -766,169 +766,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#autocommit_dml_mode; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable autocommit_dml_mode; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable autocommit_dml_mode/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-autocommit_dml_mode; NEW_CONNECTION; show variable statement_timeout; @@ -965,169 +965,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#statement_timeout; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable statement_timeout; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_timeout/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-statement_timeout; NEW_CONNECTION; set readonly = true; @@ -1192,7 +1192,7 @@ foo show variable read_timestamp; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp bar; NEW_CONNECTION; set readonly = true; @@ -1202,12 +1202,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp%; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1217,12 +1217,12 @@ _show variable read_timestamp; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp_; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1232,12 +1232,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp&; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1247,12 +1247,12 @@ $show variable read_timestamp; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp$; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1262,12 +1262,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp@; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1277,12 +1277,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp!; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1292,12 +1292,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp*; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1307,12 +1307,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp(; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1322,12 +1322,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp); NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1337,12 +1337,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp-; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1352,12 +1352,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp+; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1367,12 +1367,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp-#; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1382,12 +1382,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp/; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1397,12 +1397,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp\; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1412,12 +1412,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp?; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1427,12 +1427,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp-/; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1442,12 +1442,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp/#; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#read_timestamp; NEW_CONNECTION; set readonly = true; @@ -1457,12 +1457,12 @@ SELECT 1 AS TEST; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_timestamp/-; NEW_CONNECTION; set readonly = true; SELECT 1 AS TEST; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-read_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1513,7 +1513,7 @@ update foo set bar=1; foo show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp bar; NEW_CONNECTION; update foo set bar=1; @@ -1521,11 +1521,11 @@ update foo set bar=1; %show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp%; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1533,11 +1533,11 @@ update foo set bar=1; _show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp_; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1545,11 +1545,11 @@ update foo set bar=1; &show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp&; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1557,11 +1557,11 @@ update foo set bar=1; $show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp$; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1569,11 +1569,11 @@ update foo set bar=1; @show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp@; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1581,11 +1581,11 @@ update foo set bar=1; !show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp!; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1593,11 +1593,11 @@ update foo set bar=1; *show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp*; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1605,11 +1605,11 @@ update foo set bar=1; (show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp(; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1617,11 +1617,11 @@ update foo set bar=1; )show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp); NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1629,11 +1629,11 @@ update foo set bar=1; -show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp-; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1641,11 +1641,11 @@ update foo set bar=1; +show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp+; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1653,11 +1653,11 @@ update foo set bar=1; -#show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp-#; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1665,11 +1665,11 @@ update foo set bar=1; /show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp/; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1677,11 +1677,11 @@ update foo set bar=1; \show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp\; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1689,11 +1689,11 @@ update foo set bar=1; ?show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp?; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1701,11 +1701,11 @@ update foo set bar=1; -/show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp-/; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1713,11 +1713,11 @@ update foo set bar=1; /#show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp/#; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#commit_timestamp; NEW_CONNECTION; update foo set bar=1; @@ -1725,11 +1725,11 @@ update foo set bar=1; /-show variable commit_timestamp; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_timestamp/-; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-commit_timestamp; NEW_CONNECTION; show variable read_only_staleness; @@ -1766,169 +1766,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#read_only_staleness; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable read_only_staleness; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable read_only_staleness/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-read_only_staleness; NEW_CONNECTION; show variable optimizer_version; @@ -1965,169 +1965,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#optimizer_version; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable optimizer_version; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_version/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-optimizer_version; NEW_CONNECTION; show variable optimizer_statistics_package; @@ -2164,169 +2164,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#optimizer_statistics_package; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable optimizer_statistics_package; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable optimizer_statistics_package/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-optimizer_statistics_package; NEW_CONNECTION; show variable return_commit_stats; @@ -2363,169 +2363,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#return_commit_stats; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable return_commit_stats; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable return_commit_stats/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-return_commit_stats; NEW_CONNECTION; update foo set bar=1; @@ -2576,7 +2576,7 @@ update foo set bar=1; foo show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response bar; NEW_CONNECTION; update foo set bar=1; @@ -2584,11 +2584,11 @@ update foo set bar=1; %show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response%; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2596,11 +2596,11 @@ update foo set bar=1; _show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response_; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2608,11 +2608,11 @@ update foo set bar=1; &show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response&; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2620,11 +2620,11 @@ update foo set bar=1; $show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response$; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2632,11 +2632,11 @@ update foo set bar=1; @show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response@; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2644,11 +2644,11 @@ update foo set bar=1; !show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response!; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2656,11 +2656,11 @@ update foo set bar=1; *show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response*; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2668,11 +2668,11 @@ update foo set bar=1; (show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response(; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2680,11 +2680,11 @@ update foo set bar=1; )show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response); NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2692,11 +2692,11 @@ update foo set bar=1; -show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response-; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2704,11 +2704,11 @@ update foo set bar=1; +show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response+; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2716,11 +2716,11 @@ update foo set bar=1; -#show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response-#; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2728,11 +2728,11 @@ update foo set bar=1; /show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response/; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2740,11 +2740,11 @@ update foo set bar=1; \show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response\; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2752,11 +2752,11 @@ update foo set bar=1; ?show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response?; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2764,11 +2764,11 @@ update foo set bar=1; -/show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response-/; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2776,11 +2776,11 @@ update foo set bar=1; /#show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response/#; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#commit_response; NEW_CONNECTION; update foo set bar=1; @@ -2788,11 +2788,11 @@ update foo set bar=1; /-show variable commit_response; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable commit_response/-; NEW_CONNECTION; update foo set bar=1; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-commit_response; NEW_CONNECTION; show variable statement_tag; @@ -2829,169 +2829,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#statement_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable statement_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable statement_tag/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-statement_tag; NEW_CONNECTION; show variable transaction_tag; @@ -3028,169 +3028,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#transaction_tag; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable transaction_tag; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable transaction_tag/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-transaction_tag; NEW_CONNECTION; show variable rpc_priority; @@ -3227,169 +3227,169 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT foo show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority bar; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT %show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority%; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable%rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT _show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority_; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable_rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT &show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority&; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable&rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT $show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority$; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable$rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT @show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority@; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable@rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT !show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority!; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable!rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT *show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority*; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable*rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT (show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority(; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable(rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT )show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority); NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable)rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT +show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority+; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable+rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -#show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority-#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-#rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT \show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority\; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable\rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT ?show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority?; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable?rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT -/show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority-/; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable-/rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /#show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority/#; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/#rpc_priority; NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT /-show variable rpc_priority; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable rpc_priority/-; NEW_CONNECTION; -@EXPECT EXCEPTION INVALID_ARGUMENT +@EXPECT EXCEPTION UNIMPLEMENTED show variable/-rpc_priority; NEW_CONNECTION; begin; diff --git a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.sql b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.sql index 4091717231d..d1eabfeaec3 100644 --- a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.sql +++ b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/ConnectionImplGeneratedSqlScriptTest.sql @@ -1,23 +1,23 @@ NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -26,123 +26,125 @@ SET AUTOCOMMIT=TRUE; SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -151,58 +153,60 @@ SET READONLY=TRUE; SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:24.004000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:24.004000000Z' +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:09.176000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:09.176000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:24.004000000Z'; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:09.176000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:09.176000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -217,34 +221,34 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -253,8 +257,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -297,45 +301,46 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; BEGIN TRANSACTION; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION @@ -346,28 +351,36 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -376,123 +389,173 @@ SET AUTOCOMMIT=TRUE; SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -@EXPECT RESULT_SET 'READ_TIMESTAMP',null +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; +@EXPECT RESULT_SET 'READ_TIMESTAMP' SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -501,58 +564,78 @@ SET READONLY=TRUE; SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:24.184000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:24.184000000Z' +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:09.407000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:09.407000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:24.184000000Z'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:09.407000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:09.407000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -567,34 +650,48 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -603,8 +700,10 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -647,45 +746,62 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -NEW_CONNECTION; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; +NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; BEGIN TRANSACTION; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION @@ -696,324 +812,207 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE -SHOW VARIABLE AUTOCOMMIT; -SET AUTOCOMMIT=TRUE; -@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE -SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -ROLLBACK; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READONLY=FALSE; -@EXPECT RESULT_SET 'READONLY',FALSE -SHOW VARIABLE READONLY; -SET READONLY=TRUE; -@EXPECT RESULT_SET 'READONLY',TRUE -SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:24.391000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:24.391000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:09.583000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:09.583000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:24.391000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:09.583000000Z'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -1028,55 +1027,34 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -1085,11 +1063,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -1132,116 +1107,71 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -1250,195 +1180,125 @@ SET AUTOCOMMIT=TRUE; SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'READ_TIMESTAMP' SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -1447,85 +1307,60 @@ SET READONLY=TRUE; SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:24.603000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:24.603000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:09.731000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:09.731000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:24.603000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:09.731000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:09.731000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -1540,55 +1375,34 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -1597,11 +1411,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -1644,69 +1455,46 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; BEGIN TRANSACTION; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION @@ -1717,208 +1505,217 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=TRUE; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE +SHOW VARIABLE AUTOCOMMIT; SET AUTOCOMMIT=TRUE; +@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE +SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'READ_TIMESTAMP',null +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +@EXPECT RESULT_SET 'READ_TIMESTAMP' SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +SET READONLY=FALSE; +@EXPECT RESULT_SET 'READONLY',FALSE +SHOW VARIABLE READONLY; SET READONLY=TRUE; +@EXPECT RESULT_SET 'READONLY',TRUE +SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:24.746000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:24.746000000Z' +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:09.897000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:09.897000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:24.746000000Z'; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:09.897000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:09.897000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -1933,34 +1730,34 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -1969,8 +1766,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -2013,282 +1810,230 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; BEGIN TRANSACTION; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=TRUE; +SET AUTOCOMMIT=TRUE; SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE +SHOW VARIABLE AUTOCOMMIT; SET AUTOCOMMIT=TRUE; +@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE +SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -@EXPECT RESULT_SET 'READ_TIMESTAMP' +SET AUTOCOMMIT=TRUE; +@EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; +@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +@EXPECT RESULT_SET 'READONLY',FALSE +SHOW VARIABLE READONLY; SET READONLY=TRUE; +@EXPECT RESULT_SET 'READONLY',TRUE +SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; SET READ_ONLY_STALENESS='STRONG'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:24.942000000Z'; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:10.078000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:10.078000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:24.942000000Z'; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:10.078000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:10.078000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -2303,41 +2048,27 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -2346,9 +2077,7 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -2391,254 +2120,243 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; +@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; ABORT BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; -NEW_CONNECTION; -SET READONLY=TRUE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; +NEW_CONNECTION; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT RESULT_SET 'TEST',1 +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT RESULT_SET 'READ_TIMESTAMP' +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; +@EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READONLY=TRUE; +SET READONLY=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='STRONG'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:25.174000000Z'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:10.239000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:25.174000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:10.239000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -2652,35 +2370,35 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -2688,9 +2406,9 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -2732,220 +2450,285 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS' +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; RUN BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE -SHOW VARIABLE AUTOCOMMIT; +SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; -@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE -SHOW VARIABLE AUTOCOMMIT; -NEW_CONNECTION; -SET READONLY=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=FALSE; +NEW_CONNECTION; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; SET READONLY=FALSE; -@EXPECT RESULT_SET 'READONLY',FALSE -SHOW VARIABLE READONLY; -SET READONLY=TRUE; -@EXPECT RESULT_SET 'READONLY',TRUE -SHOW VARIABLE READONLY; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:25.357000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:25.357000000Z' +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:10.386000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:10.386000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:25.357000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:10.386000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -2959,28 +2742,42 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -2988,8 +2785,10 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -3031,68 +2830,88 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=FALSE; -NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -COMMIT; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; +COMMIT; +NEW_CONNECTION; +SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE @@ -3102,103 +2921,150 @@ SET AUTOCOMMIT=TRUE; SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; @EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION @@ -3210,7 +3076,9 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; START BATCH DML; @EXPECT EXCEPTION FAILED_PRECONDITION @@ -3222,12 +3090,17 @@ UPDATE foo SET bar=1; START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE @@ -3237,57 +3110,77 @@ SET READONLY=TRUE; SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:25.549000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:25.549000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:10.614000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:10.614000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:25.549000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:10.614000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:10.614000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' @@ -3303,33 +3196,47 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' @@ -3339,7 +3246,9 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' @@ -3383,43 +3292,61 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; BEGIN TRANSACTION; SELECT 1 AS TEST; @@ -3430,198 +3357,138 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +UPDATE foo SET bar=1; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; -SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE -SHOW VARIABLE AUTOCOMMIT; SET AUTOCOMMIT=TRUE; -@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE -SHOW VARIABLE AUTOCOMMIT; +BEGIN TRANSACTION; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; START BATCH DML; @EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @@ -3632,95 +3499,69 @@ UPDATE foo SET bar=1; START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READONLY=FALSE; -@EXPECT RESULT_SET 'READONLY',FALSE -SHOW VARIABLE READONLY; -SET READONLY=TRUE; -@EXPECT RESULT_SET 'READONLY',TRUE -SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:25.723000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:25.723000000Z' +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:10.809000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:10.809000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:25.723000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:10.809000000Z'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -3735,48 +3576,34 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -3785,10 +3612,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -3831,303 +3656,272 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -SELECT 1 AS TEST; -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -RUN BATCH; +SET AUTOCOMMIT=TRUE; +BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE +SHOW VARIABLE AUTOCOMMIT; SET AUTOCOMMIT=TRUE; +@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE +SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +START BATCH DML; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +@EXPECT RESULT_SET 'READONLY',FALSE +SHOW VARIABLE READONLY; SET READONLY=TRUE; +@EXPECT RESULT_SET 'READONLY',TRUE +SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='STRONG'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:25.858000000Z'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:10.941000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:10.941000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:25.858000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:10.941000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:10.941000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' @@ -4143,40 +3937,33 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' @@ -4186,8 +3973,7 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' @@ -4231,254 +4017,280 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +BEGIN TRANSACTION; +SELECT 1 AS TEST; +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE +SHOW VARIABLE AUTOCOMMIT; SET AUTOCOMMIT=TRUE; +@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE +SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +@EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +START BATCH DML; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +SET READONLY=FALSE; +@EXPECT RESULT_SET 'READONLY',FALSE +SHOW VARIABLE READONLY; SET READONLY=TRUE; +@EXPECT RESULT_SET 'READONLY',TRUE +SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; SET READ_ONLY_STALENESS='STRONG'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:26.003000000Z'; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:11.120000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:11.120000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:26.003000000Z'; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:11.120000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:11.120000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -4493,34 +4305,34 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -4529,8 +4341,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -4573,83 +4385,81 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -START BATCH DDL; +SET AUTOCOMMIT=TRUE; +UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -4658,167 +4468,130 @@ SET AUTOCOMMIT=TRUE; SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'READ_TIMESTAMP' SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @@ -4829,11 +4602,9 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; START BATCH DML; @EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @@ -4844,19 +4615,16 @@ UPDATE foo SET bar=1; START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -4865,85 +4633,69 @@ SET READONLY=TRUE; SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:26.155000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:26.155000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:11.271000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:11.271000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:26.155000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:11.271000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:11.271000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -4958,55 +4710,41 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -5015,11 +4753,9 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -5062,68 +4798,54 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; BEGIN TRANSACTION; SELECT 1 AS TEST; UPDATE foo SET bar=1; @@ -5133,207 +4855,232 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE +SHOW VARIABLE AUTOCOMMIT; SET AUTOCOMMIT=TRUE; +@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE +SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +@EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; -@EXPECT RESULT_SET 'READ_TIMESTAMP',null +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +@EXPECT RESULT_SET 'READ_TIMESTAMP' SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +START BATCH DML; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +SET READONLY=FALSE; +@EXPECT RESULT_SET 'READONLY',FALSE +SHOW VARIABLE READONLY; SET READONLY=TRUE; +@EXPECT RESULT_SET 'READONLY',TRUE +SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:26.311000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:26.311000000Z' +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:11.432000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:11.432000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:26.311000000Z'; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:11.432000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:11.432000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -5348,34 +5095,34 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -5384,8 +5131,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -5428,71 +5175,73 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET TRANSACTION READ ONLY; +SET AUTOCOMMIT=TRUE; +SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -5501,104 +5250,88 @@ SET AUTOCOMMIT=TRUE; SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @@ -5609,8 +5342,7 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; START BATCH DML; @EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @@ -5621,13 +5353,12 @@ UPDATE foo SET bar=1; START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -5636,58 +5367,51 @@ SET READONLY=TRUE; SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:26.437000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:26.437000000Z' +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:11.577000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:11.577000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:26.437000000Z'; +SET AUTOCOMMIT=TRUE; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:11.577000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2022-02-08T09:47:11.577000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -5702,34 +5426,27 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -5738,8 +5455,7 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -5782,44 +5498,38 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; SELECT 1 AS TEST; UPDATE foo SET bar=1; @@ -5829,40 +5539,27 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET AUTOCOMMIT=TRUE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -5870,206 +5567,124 @@ SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'AUTOCOMMIT',TRUE SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; -@EXPECT UPDATE_COUNT 1 +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; -START BATCH DML; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -UPDATE foo SET bar=1; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -6077,86 +5692,59 @@ SET READONLY=TRUE; @EXPECT RESULT_SET 'READONLY',TRUE SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:26.614000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:26.614000000Z' +COMMIT; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:11.702000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:11.702000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:26.614000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:11.702000000Z'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -6170,56 +5758,35 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -6227,12 +5794,9 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -6274,115 +5838,78 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; BEGIN TRANSACTION; SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -ROLLBACK; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -6390,206 +5917,124 @@ SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'AUTOCOMMIT',TRUE SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; -@EXPECT UPDATE_COUNT 1 +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; -START BATCH DML; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -UPDATE foo SET bar=1; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -6597,86 +6042,59 @@ SET READONLY=TRUE; @EXPECT RESULT_SET 'READONLY',TRUE SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:26.803000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:26.803000000Z' +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:11.804000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:11.804000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:26.803000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:11.804000000Z'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -6690,56 +6108,35 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -6747,12 +6144,9 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -6794,284 +6188,374 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; -@EXPECT RESULT_SET 'TEST',1 -SELECT 1 AS TEST; -COMMIT; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; BEGIN TRANSACTION; SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +NEW_CONNECTION; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -COMMIT; -NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE +SHOW VARIABLE AUTOCOMMIT; SET AUTOCOMMIT=TRUE; +@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE +SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -@EXPECT UPDATE_COUNT 1 +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +ROLLBACK; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -START BATCH DML; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -UPDATE foo SET bar=1; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +SET READONLY=FALSE; +@EXPECT RESULT_SET 'READONLY',FALSE +SHOW VARIABLE READONLY; SET READONLY=TRUE; +@EXPECT RESULT_SET 'READONLY',TRUE +SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:26.930000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:26.930000000Z' +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:11.962000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:11.962000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:26.930000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:11.962000000Z'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -7085,35 +6569,56 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -7121,9 +6626,12 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -7165,287 +6673,401 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE +SHOW VARIABLE AUTOCOMMIT; SET AUTOCOMMIT=TRUE; +@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE +SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT UPDATE_COUNT 1 +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT RESULT_SET 'READ_TIMESTAMP',null +COMMIT; +@EXPECT RESULT_SET 'READ_TIMESTAMP' SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -START BATCH DML; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -UPDATE foo SET bar=1; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; +SET READONLY=FALSE; +@EXPECT RESULT_SET 'READONLY',FALSE +SHOW VARIABLE READONLY; SET READONLY=TRUE; +@EXPECT RESULT_SET 'READONLY',TRUE +SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; SET READ_ONLY_STALENESS='STRONG'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:27.097000000Z'; +COMMIT; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:12.213000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:12.213000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:27.097000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:12.213000000Z'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -7459,42 +7081,56 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -7502,10 +7138,12 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -7547,260 +7185,282 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; +BEGIN TRANSACTION; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=TRUE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT UPDATE_COUNT 1 +BEGIN TRANSACTION; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +BEGIN TRANSACTION; SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -START BATCH DML; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -UPDATE foo SET bar=1; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION SET READONLY=TRUE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +BEGIN TRANSACTION; SET READ_ONLY_STALENESS='STRONG'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:27.270000000Z'; +BEGIN TRANSACTION; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:12.372000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:12.372000000Z' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:27.270000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:12.372000000Z'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +BEGIN TRANSACTION; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +BEGIN TRANSACTION; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' +SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -7814,35 +7474,35 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -7850,9 +7510,9 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -7894,230 +7554,283 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SELECT 1 AS TEST; +BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE -SHOW VARIABLE AUTOCOMMIT; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=TRUE; -@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE -SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -@EXPECT UPDATE_COUNT 1 +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'READ_TIMESTAMP',null +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT RESULT_SET 'READ_TIMESTAMP' SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -START BATCH DML; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SET READONLY=FALSE; -@EXPECT RESULT_SET 'READONLY',FALSE -SHOW VARIABLE READONLY; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READONLY=TRUE; -@EXPECT RESULT_SET 'READONLY',TRUE -SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='STRONG'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:27.406000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:27.406000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:12.493000000Z'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:27.406000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:12.493000000Z'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -8131,28 +7844,42 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -8160,8 +7887,10 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -8203,241 +7932,255 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=TRUE; +NEW_CONNECTION; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; -@EXPECT RESULT_SET 'READ_TIMESTAMP',null +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; +@EXPECT RESULT_SET 'READ_TIMESTAMP' SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; ROLLBACK; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READONLY=FALSE; +SET READONLY=TRUE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='STRONG'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:27.519000000Z'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:12.629000000Z'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:27.519000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:12.629000000Z'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -8451,35 +8194,35 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -8487,9 +8230,9 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -8531,285 +8274,220 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -START BATCH DDL; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -NEW_CONNECTION; -SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE +SHOW VARIABLE AUTOCOMMIT; SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE +SHOW VARIABLE AUTOCOMMIT; +NEW_CONNECTION; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; -NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +NEW_CONNECTION; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; ROLLBACK; NEW_CONNECTION; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; -@EXPECT EXCEPTION FAILED_PRECONDITION -SET READONLY=FALSE; +@EXPECT RESULT_SET 'READONLY',FALSE +SHOW VARIABLE READONLY; +SET READONLY=TRUE; +@EXPECT RESULT_SET 'READONLY',TRUE +SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:27.620000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:27.620000000Z' +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:12.745000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:12.745000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:27.620000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:12.745000000Z'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -8823,42 +8501,28 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -8866,10 +8530,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -8911,88 +8573,68 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION READ ONLY; +SET READONLY=TRUE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE @@ -9002,150 +8644,103 @@ SET AUTOCOMMIT=TRUE; SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; -SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION @@ -9157,9 +8752,7 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; START BATCH DML; @EXPECT EXCEPTION FAILED_PRECONDITION @@ -9171,17 +8764,12 @@ UPDATE foo SET bar=1; START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE @@ -9191,77 +8779,57 @@ SET READONLY=TRUE; SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:27.738000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:27.738000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:12.848000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:12.848000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:27.738000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:27.738000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:12.848000000Z'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' @@ -9277,47 +8845,33 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' @@ -9327,9 +8881,7 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' @@ -9373,61 +8925,43 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; BEGIN TRANSACTION; SELECT 1 AS TEST; @@ -9438,138 +8972,198 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE +SHOW VARIABLE AUTOCOMMIT; +SET AUTOCOMMIT=TRUE; +@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE +SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -NEW_CONNECTION; -SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; +NEW_CONNECTION; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; START BATCH DML; @EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @@ -9580,69 +9174,95 @@ UPDATE foo SET bar=1; START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; SET READONLY=FALSE; +@EXPECT RESULT_SET 'READONLY',FALSE +SHOW VARIABLE READONLY; +SET READONLY=TRUE; +@EXPECT RESULT_SET 'READONLY',TRUE +SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:27.876000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:27.876000000Z' +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:12.981000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:12.981000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:27.876000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:12.981000000Z'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -9657,34 +9277,48 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -9693,8 +9327,10 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -9737,272 +9373,303 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; -SET TRANSACTION_TAG = 'some-tag'; -NEW_CONNECTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; +SET TRANSACTION_TAG = 'some-tag'; +NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; BEGIN TRANSACTION; +SELECT 1 AS TEST; +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -BEGIN TRANSACTION; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE -SHOW VARIABLE AUTOCOMMIT; +START BATCH DDL; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=TRUE; -@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE -SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT UPDATE_COUNT 1 +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT RESULT_SET 'TEST',1 +@EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' +@EXPECT EXCEPTION FAILED_PRECONDITION SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +SET AUTOCOMMIT=FALSE; START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -START BATCH DML; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -SET READONLY=FALSE; -@EXPECT RESULT_SET 'READONLY',FALSE -SHOW VARIABLE READONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READONLY=TRUE; -@EXPECT RESULT_SET 'READONLY',TRUE -SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='STRONG'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:28.014000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:28.014000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:13.109000000Z'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:28.014000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:28.014000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:13.109000000Z'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' @@ -10018,33 +9685,40 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' @@ -10054,7 +9728,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' @@ -10098,280 +9773,254 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT RESULT_SET 'READ_ONLY_STALENESS' +@EXPECT EXCEPTION FAILED_PRECONDITION SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -BEGIN TRANSACTION; -SELECT 1 AS TEST; -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION -ABORT BATCH; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE -SHOW VARIABLE AUTOCOMMIT; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=TRUE; -@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE -SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -@EXPECT UPDATE_COUNT 1 +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -@EXPECT RESULT_SET 'TEST',1 +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -START BATCH DML; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -SET READONLY=FALSE; -@EXPECT RESULT_SET 'READONLY',FALSE -SHOW VARIABLE READONLY; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READONLY=TRUE; -@EXPECT RESULT_SET 'READONLY',TRUE -SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='STRONG'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:28.150000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:28.150000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:13.229000000Z'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:28.150000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:28.150000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:13.229000000Z'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -10386,34 +10035,34 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -10422,8 +10071,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -10466,81 +10115,83 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS' +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +START BATCH DDL; RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; -BEGIN TRANSACTION; -SELECT 1 AS TEST; -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +SET AUTOCOMMIT=FALSE; +START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -10549,130 +10200,167 @@ SET AUTOCOMMIT=TRUE; SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'READ_TIMESTAMP' SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @@ -10683,9 +10371,11 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; START BATCH DML; @EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @@ -10696,16 +10386,19 @@ UPDATE foo SET bar=1; START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -10714,69 +10407,85 @@ SET READONLY=TRUE; SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:28.249000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:28.249000000Z' +COMMIT; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:13.350000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:13.350000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:28.249000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:28.249000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:13.350000000Z'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -10791,41 +10500,55 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -10834,9 +10557,11 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -10879,54 +10604,68 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +COMMIT; SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; BEGIN TRANSACTION; SELECT 1 AS TEST; UPDATE foo SET bar=1; @@ -10936,232 +10675,207 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE -SHOW VARIABLE AUTOCOMMIT; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=TRUE; -@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE -SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -@EXPECT UPDATE_COUNT 1 +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -@EXPECT RESULT_SET 'READ_TIMESTAMP' +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; +@EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -START BATCH DDL; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -START BATCH DML; -@EXPECT EXCEPTION FAILED_PRECONDITION -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -UPDATE foo SET bar=1; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -SET READONLY=FALSE; -@EXPECT RESULT_SET 'READONLY',FALSE -SHOW VARIABLE READONLY; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READONLY=TRUE; -@EXPECT RESULT_SET 'READONLY',TRUE -SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:28.377000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:28.377000000Z' +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:13.472000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:13.472000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:28.377000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:28.377000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:13.472000000Z'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -11176,34 +10890,34 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -11212,8 +10926,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -11256,73 +10970,71 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -BEGIN TRANSACTION; -SELECT 1 AS TEST; -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET AUTOCOMMIT=FALSE; +SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -NEW_CONNECTION; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -11331,88 +11043,104 @@ SET AUTOCOMMIT=TRUE; SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; -@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' -SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET TRANSACTION READ ONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET TRANSACTION READ WRITE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @@ -11423,7 +11151,8 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); START BATCH DDL; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; START BATCH DML; @EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @@ -11434,12 +11163,13 @@ UPDATE foo SET bar=1; START BATCH DML; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; ROLLBACK; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -11448,51 +11178,58 @@ SET READONLY=TRUE; SHOW VARIABLE READONLY; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:28.469000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:28.469000000Z' +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:13.568000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:13.568000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:28.469000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:28.469000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:13.568000000Z'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -11507,27 +11244,34 @@ SET OPTIMIZER_VERSION=''; SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -11536,7 +11280,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -11579,38 +11324,44 @@ SET STATEMENT_TIMEOUT='0ns'; SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; COMMIT; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; BEGIN TRANSACTION; SELECT 1 AS TEST; UPDATE foo SET bar=1; @@ -11620,27 +11371,40 @@ CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); BEGIN TRANSACTION; NEW_CONNECTION; SET READONLY=FALSE; -SET AUTOCOMMIT=TRUE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -11648,126 +11412,206 @@ SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'AUTOCOMMIT',TRUE SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +@EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +START BATCH DML; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -11775,61 +11619,86 @@ SET READONLY=TRUE; @EXPECT RESULT_SET 'READONLY',TRUE SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:28.552000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:28.552000000Z' +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:13.700000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:13.700000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:28.552000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:28.552000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:13.700000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -11843,35 +11712,56 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -11879,9 +11769,12 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -11923,85 +11816,113 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; BEGIN TRANSACTION; SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; SET AUTOCOMMIT=FALSE; @@ -12011,172 +11932,204 @@ SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'AUTOCOMMIT',TRUE SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -@EXPECT RESULT_SET 'READ_TIMESTAMP' +@EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; +START BATCH DML; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; SET READONLY=FALSE; @@ -12186,77 +12139,84 @@ SET READONLY=TRUE; @EXPECT RESULT_SET 'READONLY',TRUE SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:28.668000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:28.668000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:13.931000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:13.931000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:28.668000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:28.668000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:13.931000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; SET OPTIMIZER_VERSION='1'; @@ -12272,47 +12232,54 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -@EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null +@EXPECT RESULT_SET 'COMMIT_TIMESTAMP' SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @@ -12322,9 +12289,10 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; SET STATEMENT_TIMEOUT='1s'; @@ -12368,273 +12336,283 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; BEGIN TRANSACTION; SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET AUTOCOMMIT=FALSE; -NEW_CONNECTION; -SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; +NEW_CONNECTION; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; +START BATCH DML; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READONLY=FALSE; -NEW_CONNECTION; SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +NEW_CONNECTION; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:28.767000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:28.767000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:14.114000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:14.114000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:28.767000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:14.114000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' @@ -12649,34 +12627,34 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' @@ -12685,8 +12663,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' @@ -12729,260 +12707,286 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -@EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE -SHOW VARIABLE AUTOCOMMIT; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=TRUE; -@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE -SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT RESULT_SET 'READ_TIMESTAMP' +@EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +START BATCH DML; +@EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; SET READONLY=FALSE; -@EXPECT RESULT_SET 'READONLY',FALSE -SHOW VARIABLE READONLY; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READONLY=TRUE; -@EXPECT RESULT_SET 'READONLY',TRUE -SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='STRONG'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:28.862000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:28.862000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:14.244000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:28.862000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:28.862000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:14.244000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' @@ -12997,34 +13001,41 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' @@ -13033,8 +13044,9 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' @@ -13077,267 +13089,259 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -BEGIN TRANSACTION; -SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 +SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; +SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; -@EXPECT RESULT_SET 'AUTOCOMMIT',FALSE -SHOW VARIABLE AUTOCOMMIT; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT=TRUE; -@EXPECT RESULT_SET 'AUTOCOMMIT',TRUE -SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION +@EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; -@EXPECT RESULT_SET 'READ_TIMESTAMP' +@EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; +START BATCH DML; +@EXPECT EXCEPTION FAILED_PRECONDITION SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +UPDATE foo SET bar=1; +@EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; SET READONLY=FALSE; -@EXPECT RESULT_SET 'READONLY',FALSE -SHOW VARIABLE READONLY; +SET AUTOCOMMIT=FALSE; +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READONLY=TRUE; -@EXPECT RESULT_SET 'READONLY',TRUE -SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='STRONG'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:28.959000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:28.959000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:14.384000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:28.959000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:28.959000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:14.384000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' @@ -13352,34 +13356,34 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' @@ -13388,8 +13392,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' @@ -13432,75 +13436,68 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SELECT 1 AS TEST; -BEGIN TRANSACTION; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -UPDATE foo SET bar=1; -@EXPECT EXCEPTION FAILED_PRECONDITION -CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -@EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'OPTIMIZER_VERSION' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION ABORT BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT',FALSE SHOW VARIABLE AUTOCOMMIT; @@ -13508,102 +13505,110 @@ SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'AUTOCOMMIT',TRUE SHOW VARIABLE AUTOCOMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT UPDATE_COUNT 1 UPDATE foo SET bar=1; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION SET AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE' SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET TRANSACTION READ ONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET TRANSACTION READ WRITE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'READ_TIMESTAMP',null SHOW VARIABLE READ_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +START BATCH DDL; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +UPDATE foo SET bar=1; +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DDL; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +START BATCH DML; +@EXPECT EXCEPTION FAILED_PRECONDITION +SELECT 1 AS TEST; +@EXPECT EXCEPTION FAILED_PRECONDITION +CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); +UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION START BATCH DML; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; ROLLBACK; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET READONLY=FALSE; @EXPECT RESULT_SET 'READONLY',FALSE SHOW VARIABLE READONLY; @@ -13611,52 +13616,50 @@ SET READONLY=TRUE; @EXPECT RESULT_SET 'READONLY',TRUE SHOW VARIABLE READONLY; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET READ_ONLY_STALENESS='STRONG'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','STRONG' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2021-11-12T19:08:29.047000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2021-11-12T19:08:29.047000000Z' +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2022-02-08T09:47:14.507000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2022-02-08T09:47:14.507000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2021-11-12T19:08:29.047000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2021-11-12T19:08:29.047000000Z' -SHOW VARIABLE READ_ONLY_STALENESS; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT EXCEPTION FAILED_PRECONDITION +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2022-02-08T09:47:14.507000000Z'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET READ_ONLY_STALENESS='EXACT_STALENESS 1s'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 1s' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; +@EXPECT EXCEPTION FAILED_PRECONDITION SET READ_ONLY_STALENESS='MAX_STALENESS 100ms'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MAX_STALENESS 100ms' -SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET READ_ONLY_STALENESS='EXACT_STALENESS 100us'; @EXPECT RESULT_SET 'READ_ONLY_STALENESS','EXACT_STALENESS 100us' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_RESPONSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET OPTIMIZER_VERSION='1'; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','1' SHOW VARIABLE OPTIMIZER_VERSION; @@ -13670,28 +13673,28 @@ SET OPTIMIZER_VERSION=''; @EXPECT RESULT_SET 'OPTIMIZER_VERSION','' SHOW VARIABLE OPTIMIZER_VERSION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'COMMIT_TIMESTAMP',null SHOW VARIABLE COMMIT_TIMESTAMP; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET OPTIMIZER_STATISTICS_PACKAGE='custom-package'; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','custom-package' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; @@ -13699,8 +13702,8 @@ SET OPTIMIZER_STATISTICS_PACKAGE=''; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE','' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET STATEMENT_TIMEOUT='1s'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT','1s' SHOW VARIABLE STATEMENT_TIMEOUT; @@ -13742,47 +13745,44 @@ SET STATEMENT_TIMEOUT='0ns'; @EXPECT RESULT_SET 'STATEMENT_TIMEOUT',null SHOW VARIABLE STATEMENT_TIMEOUT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'READ_ONLY_STALENESS' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; COMMIT; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'OPTIMIZER_STATISTICS_PACKAGE' SHOW VARIABLE OPTIMIZER_STATISTICS_PACKAGE; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION RUN BATCH; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; -@EXPECT EXCEPTION FAILED_PRECONDITION +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; SET TRANSACTION_TAG = 'some-tag'; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; SELECT 1 AS TEST; -@EXPECT EXCEPTION FAILED_PRECONDITION UPDATE foo SET bar=1; @EXPECT EXCEPTION FAILED_PRECONDITION CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION BEGIN TRANSACTION; NEW_CONNECTION; -SET READONLY=TRUE; -SET AUTOCOMMIT=TRUE; +SET READONLY=FALSE; +SET AUTOCOMMIT=FALSE; diff --git a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/PostgreSQLCommentsTest.sql b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/PostgreSQLCommentsTest.sql new file mode 100644 index 00000000000..51ae1e7203c --- /dev/null +++ b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/PostgreSQLCommentsTest.sql @@ -0,0 +1,187 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@EXPECT 'SELECT 1'; +SELECT 1; +-- This is a single line comment +SELECT 1; +/* This is a multi line comment on one line */ +SELECT 1; +/* This + is + a + multiline + comment +*/ +SELECT 1; +/* This + * is + * a + * multiline + * comment + */ +SELECT 1; +/** This is a javadoc style comment on one line*/ +SELECT 1; +/** This + is + a + javadoc + style + comment + on + multiple + lines +*/ +SELECT 1; +/** This + * is + * a + * javadoc + * style + * comment + * on + * multiple + * lines + */ +SELECT 1; + +@EXPECT 'SELECT + 1'; +-- First comment +SELECT-- second comment + 1; +-- First comment +SELECT-- second comment + 1--third comment +; +@EXPECT 'SELECT + 1'; +/* First comment */ +SELECT/* second comment */ + 1; +/* First comment */ +SELECT/* second comment */ + 1/* Third comment */ +; + + +@EXPECT 'SELECT + 1'; +-- First comment +SELECT -- second comment + 1 ; +-- First comment +SELECT -- second comment + 1 --third comment +; +@EXPECT 'SELECT + 1'; +/* First comment */ +SELECT /* second comment */ + 1 ; +/* First comment */ +SELECT /* second comment */ + 1 /* Third comment */ +; + +@EXPECT 'SELECT "TEST -- This is not a comment"'; +SELECT "TEST -- This is not a comment"; +-- This is a comment +SELECT "TEST -- This is not a comment"; +-- This is a comment +SELECT "TEST -- This is not a comment" -- This is a comment; + + @EXPECT 'SELECT "TEST /* This is not a comment */"'; +SELECT "TEST /* This is not a comment */"; +/* This is a comment */ +SELECT "TEST /* This is not a comment */"; +/* This is a comment */ +SELECT "TEST /* This is not a comment */" /* This is a comment */; + +@EXPECT 'SELECT 'TEST -- This is not a comment''; +SELECT 'TEST -- This is not a comment'; +-- This is a comment +SELECT 'TEST -- This is not a comment'; +-- This is a comment +SELECT 'TEST -- This is not a comment' -- This is a comment; + + @EXPECT 'SELECT 'TEST /* This is not a comment */''; +SELECT 'TEST /* This is not a comment */'; +/* This is a comment */ +SELECT 'TEST /* This is not a comment */'; +/* This is a comment */ +SELECT 'TEST /* This is not a comment */' /* This is a comment */; + +@EXPECT 'SELECT $$TEST +-- This is not a comment +$$'; +SELECT $$TEST +-- This is not a comment +$$; +-- This is a comment +SELECT $$TEST +-- This is not a comment +$$; +-- This is a comment +SELECT $$TEST +-- This is not a comment +$$ -- This is a comment; + + @EXPECT 'SELECT $$TEST +/* This is not a comment */ +$$'; +SELECT $$TEST +/* This is not a comment */ +$$; +/* This is a comment */ +SELECT $$TEST +/* This is not a comment */ +$$; +/* This is a comment */ +SELECT $$TEST +/* This is not a comment */ +$$ /* This is a comment */; + +@EXPECT 'SELECT 1'; +/* This is a comment /* This is an embedded comment */ This is still a comment */ +SELECT 1; +/** This is a javadoc style comment /* This is an embedded comment */ This is still a comment */ +SELECT 1; +/** This is a javadoc style comment /** This is an embedded comment */ This is still a comment */ +SELECT 1; +/** This is a javadoc style comment /** This is an embedded comment **/ This is still a comment **/ +SELECT 1; +/* multiline comment + * with nesting: /* nested block comment */ + */ +SELECT 1; + +@EXPECT 'SELECT U&"d\0061t\+000061" FROM FOO'; +SELECT U&"d\0061t\+000061" FROM FOO; +/* This is a comment /* U&"d\0061t\+000061" */ This is still a comment */ +SELECT U&"d\0061t\+000061" FROM FOO; +SELECT U&"d\0061t\+000061" /* This is a comment /* U&"d\0061t\+000061" */ This is still a comment */FROM FOO; + +@EXPECT 'SELECT U&"d\0061t\+000061" +FROM FOO'; +SELECT U&"d\0061t\+000061" -- U&"d\0061t\+000061" == data */ This is still a comment */ +FROM FOO; + +@EXPECT 'SELECT 'foo' +'bar' +SELECT 'foo' -- This is allowed in PostgreSQL +'bar';