diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index 7ab67b223ec..d779decd658 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -21,6 +21,8 @@ branchProtectionRules: - compile (11) - units-with-multiplexed-session (8) - units-with-multiplexed-session (11) + - unmanaged_dependency_check + - library_generation - pattern: 3.3.x isAdminEnforced: true requiredApprovingReviewCount: 1 diff --git a/.kokoro/build.sh b/.kokoro/build.sh index f8ae5a96f37..d603c59859b 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -113,8 +113,8 @@ integration-directpath-enabled) -Dclirr.skip=true \ -Denforcer.skip=true \ -Dmaven.main.skip=true \ - -Dspanner.gce.config.project_id=gcloud-devel \ - -Dspanner.testenv.instance=projects/gcloud-devel/instances/java-client-integration-tests-directpath \ + -Dspanner.testenv.instance=projects/span-cloud-testing/instances/spanner-java-client-directpath \ + -Dspanner.gce.config.project_id=span-cloud-testing \ -fae \ verify RETURN_CODE=$? diff --git a/.kokoro/nightly/integration-directpath-enabled.cfg b/.kokoro/nightly/integration-directpath-enabled.cfg index 65ad1785992..e8d750a34a7 100644 --- a/.kokoro/nightly/integration-directpath-enabled.cfg +++ b/.kokoro/nightly/integration-directpath-enabled.cfg @@ -28,12 +28,12 @@ env_vars: { env_vars: { key: "GOOGLE_APPLICATION_CREDENTIALS" - value: "secret_manager/java-it-service-account" + value: "secret_manager/java-client-testing" } env_vars: { key: "SECRET_MANAGER_KEYS" - value: "java-it-service-account" + value: "java-client-testing" } env_vars: { diff --git a/.kokoro/presubmit/integration-directpath-enabled.cfg b/.kokoro/presubmit/integration-directpath-enabled.cfg index ab24b385496..e619d7e8207 100644 --- a/.kokoro/presubmit/integration-directpath-enabled.cfg +++ b/.kokoro/presubmit/integration-directpath-enabled.cfg @@ -24,12 +24,12 @@ env_vars: { env_vars: { key: "GOOGLE_APPLICATION_CREDENTIALS" - value: "secret_manager/java-it-service-account" + value: "secret_manager/java-client-testing" } env_vars: { key: "SECRET_MANAGER_KEYS" - value: "java-it-service-account" + value: "java-client-testing" } env_vars: { diff --git a/.kokoro/readme.sh b/.kokoro/readme.sh deleted file mode 100755 index 40d44268bec..00000000000 --- a/.kokoro/readme.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash -# 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. - -set -eo pipefail - -cd ${KOKORO_ARTIFACTS_DIR}/github/java-spanner - -# Disable buffering, so that the logs stream through. -export PYTHONUNBUFFERED=1 - -# Kokoro exposes this as a file, but the scripts expect just a plain variable. -export GITHUB_TOKEN=$(cat ${KOKORO_KEYSTORE_DIR}/73713_yoshi-automation-github-key) - -# Setup git credentials -echo "https://${GITHUB_TOKEN}:@github.com" >> ~/.git-credentials -git config --global credential.helper 'store --file ~/.git-credentials' - -python3.6 -m pip install git+https://github.com/googleapis/synthtool.git#egg=gcp-synthtool - -set +e -python3.6 -m autosynth.synth \ - --repository=googleapis/java-spanner \ - --synth-file-name=.github/readme/synth.py \ - --metadata-path=.github/readme/synth.metadata \ - --pr-title="chore: regenerate README" \ - --branch-suffix="readme" - -# autosynth returns 28 to signal there are no changes -RETURN_CODE=$? -if [[ ${RETURN_CODE} -ne 0 && ${RETURN_CODE} -ne 28 ]] -then - exit ${RETURN_CODE} -fi diff --git a/.repo-metadata.json b/.repo-metadata.json index 7848b32f2b6..670b37d595a 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -2,7 +2,7 @@ "api_shortname": "spanner", "name_pretty": "Cloud Spanner", "product_documentation": "https://cloud.google.com/spanner/docs/", - "api_description": "is a fully managed, mission-critical, relational database service that offers transactional consistency at global scale, \\nschemas, SQL (ANSI 2011 with extensions), and automatic, synchronous replication \\nfor high availability.\\n\\nBe sure to activate the Cloud Spanner API on the Developer's Console to\\nuse Cloud Spanner from your project.", + "api_description": "is a fully managed, mission-critical, relational database service that offers transactional consistency at global scale, schemas, SQL (ANSI 2011 with extensions), and automatic, synchronous replication for high availability. Be sure to activate the Cloud Spanner API on the Developer's Console to use Cloud Spanner from your project.", "client_documentation": "https://cloud.google.com/java/docs/reference/google-cloud-spanner/latest/history", "release_level": "stable", "transport": "grpc", diff --git a/CHANGELOG.md b/CHANGELOG.md index 395574d2ab1..1436e341430 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## [6.82.0](https://github.com/googleapis/java-spanner/compare/v6.81.2...v6.82.0) (2024-12-04) + + +### Features + +* Add option for retrying DML as PDML ([#3480](https://github.com/googleapis/java-spanner/issues/3480)) ([b545557](https://github.com/googleapis/java-spanner/commit/b545557b1a27868aeb5115b3947d42db015cc00e)) +* Add the last statement option to ExecuteSqlRequest and ExecuteBatchDmlRequest ([76ab801](https://github.com/googleapis/java-spanner/commit/76ab8011b0aa03e5bb98e375595358732cde31b7)) + + +### Bug Fixes + +* **deps:** Update the Java code generator (gapic-generator-java) to 2.50.0 ([76ab801](https://github.com/googleapis/java-spanner/commit/76ab8011b0aa03e5bb98e375595358732cde31b7)) +* Shutdown built in metrics meter provider ([#3518](https://github.com/googleapis/java-spanner/issues/3518)) ([c935e2e](https://github.com/googleapis/java-spanner/commit/c935e2eff780100273bc35c11458485c9bb05230)) +* **spanner:** GetEdition() is returning null for Instance ([#3496](https://github.com/googleapis/java-spanner/issues/3496)) ([77cb585](https://github.com/googleapis/java-spanner/commit/77cb585d57fd30f953b0ffb80be124e3cb1c6f39)) + + +### Dependencies + +* Update dependency commons-io:commons-io to v2.18.0 ([#3492](https://github.com/googleapis/java-spanner/issues/3492)) ([5c8b3ad](https://github.com/googleapis/java-spanner/commit/5c8b3ade163b4cdb81a53f5dcf777ebba48ef265)) + + +### Documentation + +* Add Multi Region Encryption samples ([#3524](https://github.com/googleapis/java-spanner/issues/3524)) ([316f971](https://github.com/googleapis/java-spanner/commit/316f97146a1fb9f120b642421ec1196be9abddf0)) + ## [6.81.2](https://github.com/googleapis/java-spanner/compare/v6.81.1...v6.81.2) (2024-11-20) diff --git a/README.md b/README.md index 294ac252fd3..29f1bb0322d 100644 --- a/README.md +++ b/README.md @@ -56,13 +56,13 @@ implementation 'com.google.cloud:google-cloud-spanner' If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-spanner:6.81.1' +implementation 'com.google.cloud:google-cloud-spanner:6.82.0' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.81.1" +libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.82.0" ``` ## Authentication @@ -91,7 +91,7 @@ to add `google-cloud-spanner` as a dependency in your code. ## About Cloud Spanner -[Cloud Spanner][product-docs] is a fully managed, mission-critical, relational database service that offers transactional consistency at global scale, \nschemas, SQL (ANSI 2011 with extensions), and automatic, synchronous replication \nfor high availability.\n\nBe sure to activate the Cloud Spanner API on the Developer's Console to\nuse Cloud Spanner from your project. +[Cloud Spanner][product-docs] is a fully managed, mission-critical, relational database service that offers transactional consistency at global scale, schemas, SQL (ANSI 2011 with extensions), and automatic, synchronous replication for high availability. Be sure to activate the Cloud Spanner API on the Developer's Console to use Cloud Spanner from your project. See the [Cloud Spanner client library docs][javadocs] to learn how to use this Cloud Spanner Client Library. @@ -505,9 +505,12 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/ | Batch Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/BatchSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/BatchSample.java) | | Batch Write At Least Once Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/BatchWriteAtLeastOnceSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/BatchWriteAtLeastOnceSample.java) | | Copy Backup Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CopyBackupSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CopyBackupSample.java) | +| Copy Backup With Multi Region Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CopyBackupWithMultiRegionEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CopyBackupWithMultiRegionEncryptionKey.java) | | Create Backup With Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateBackupWithEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateBackupWithEncryptionKey.java) | +| Create Backup With Multi Region Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateBackupWithMultiRegionEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateBackupWithMultiRegionEncryptionKey.java) | | Create Database With Default Leader Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithDefaultLeaderSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithDefaultLeaderSample.java) | | Create Database With Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithEncryptionKey.java) | +| Create Database With Multi Region Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithMultiRegionEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithMultiRegionEncryptionKey.java) | | Create Database With Version Retention Period Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithVersionRetentionPeriodSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithVersionRetentionPeriodSample.java) | | Create Full Backup Schedule Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateFullBackupScheduleSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateFullBackupScheduleSample.java) | | Create Incremental Backup Schedule Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/CreateIncrementalBackupScheduleSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/CreateIncrementalBackupScheduleSample.java) | @@ -560,6 +563,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/ | Quickstart Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QuickstartSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/QuickstartSample.java) | | Read Data With Database Role | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/ReadDataWithDatabaseRole.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/ReadDataWithDatabaseRole.java) | | Restore Backup With Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithEncryptionKey.java) | +| Restore Backup With Multi Region Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithMultiRegionEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithMultiRegionEncryptionKey.java) | | Set Max Commit Delay Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/SetMaxCommitDelaySample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/SetMaxCommitDelaySample.java) | | Singer Proto | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/SingerProto.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/SingerProto.java) | | Spanner Graph Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java) | @@ -721,7 +725,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-spanner/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-spanner.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-spanner/6.81.1 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-spanner/6.82.0 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index bfb403e8b5f..22c13635ce8 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -24,7 +24,7 @@ com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 diff --git a/generation_config.yaml b/generation_config.yaml index c5c16b838c9..ef44b5b9dea 100644 --- a/generation_config.yaml +++ b/generation_config.yaml @@ -1,12 +1,12 @@ -gapic_generator_version: 2.49.0 -googleapis_commitish: c72f219fedbb57d3f83c10550e135c4824b670eb +gapic_generator_version: 2.50.0 +googleapis_commitish: 349841abac6c3e580ccce6e3d6fcc182ed2512c2 libraries_bom_version: 26.50.0 libraries: - api_shortname: spanner name_pretty: Cloud Spanner product_documentation: https://cloud.google.com/spanner/docs/ client_documentation: https://cloud.google.com/java/docs/reference/google-cloud-spanner/latest/history - api_description: is a fully managed, mission-critical, relational database service that offers transactional consistency at global scale, \nschemas, SQL (ANSI 2011 with extensions), and automatic, synchronous replication \nfor high availability.\n\nBe sure to activate the Cloud Spanner API on the Developer's Console to\nuse Cloud Spanner from your project. + api_description: is a fully managed, mission-critical, relational database service that offers transactional consistency at global scale, schemas, SQL (ANSI 2011 with extensions), and automatic, synchronous replication for high availability. Be sure to activate the Cloud Spanner API on the Developer's Console to use Cloud Spanner from your project. issue_tracker: https://issuetracker.google.com/issues?q=componentid:190851%2B%20status:open release_level: stable language: java diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index e3daac22258..1db01f10946 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner-bom - 6.81.2 + 6.82.0 pom com.google.cloud @@ -53,43 +53,43 @@ com.google.cloud google-cloud-spanner - 6.81.2 + 6.82.0 com.google.cloud google-cloud-spanner test-jar - 6.81.2 + 6.82.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.81.2 + 6.82.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.81.2 + 6.82.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.81.2 + 6.82.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.81.2 + 6.82.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.81.2 + 6.82.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.81.2 + 6.82.0 diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index 6aaf0ad73c1..c108b69b1a3 100644 --- a/google-cloud-spanner-executor/pom.xml +++ b/google-cloud-spanner-executor/pom.xml @@ -5,14 +5,14 @@ 4.0.0 com.google.cloud google-cloud-spanner-executor - 6.81.2 + 6.82.0 jar Google Cloud Spanner Executor com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 @@ -169,7 +169,7 @@ commons-io commons-io - 2.17.0 + 2.18.0 diff --git a/google-cloud-spanner/clirr-ignored-differences.xml b/google-cloud-spanner/clirr-ignored-differences.xml index ec13415790c..bae308f2b50 100644 --- a/google-cloud-spanner/clirr-ignored-differences.xml +++ b/google-cloud-spanner/clirr-ignored-differences.xml @@ -791,4 +791,22 @@ boolean isAutoBatchDmlUpdateCountVerification() + + + 7012 + com/google/cloud/spanner/connection/TransactionRetryListener + void retryDmlAsPartitionedDmlStarting(java.util.UUID, com.google.cloud.spanner.Statement, com.google.cloud.spanner.TransactionMutationLimitExceededException) + + + 7012 + com/google/cloud/spanner/connection/TransactionRetryListener + void retryDmlAsPartitionedDmlFinished(java.util.UUID, com.google.cloud.spanner.Statement, long) + + + 7012 + com/google/cloud/spanner/connection/TransactionRetryListener + void retryDmlAsPartitionedDmlFailed(java.util.UUID, com.google.cloud.spanner.Statement, java.lang.Throwable) + + + diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 845e8bfeef8..b7589c10203 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner - 6.81.2 + 6.82.0 jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 google-cloud-spanner diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BuiltInOpenTelemetryMetricsProvider.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BuiltInOpenTelemetryMetricsProvider.java index 9367c45b636..8f4ada6ae57 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BuiltInOpenTelemetryMetricsProvider.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BuiltInOpenTelemetryMetricsProvider.java @@ -65,8 +65,9 @@ OpenTelemetry getOrCreateOpenTelemetry(String projectId, @Nullable Credentials c SdkMeterProviderBuilder sdkMeterProviderBuilder = SdkMeterProvider.builder(); BuiltInOpenTelemetryMetricsView.registerBuiltinMetrics( SpannerCloudMonitoringExporter.create(projectId, credentials), sdkMeterProviderBuilder); - this.openTelemetry = - OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProviderBuilder.build()).build(); + SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); + this.openTelemetry = OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build(); + Runtime.getRuntime().addShutdownHook(new Thread(sdkMeterProvider::close)); } return this.openTelemetry; } catch (IOException ex) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Instance.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Instance.java index 04933a67121..4e4bb092702 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Instance.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Instance.java @@ -24,6 +24,7 @@ import com.google.longrunning.Operation; import com.google.spanner.admin.database.v1.CreateDatabaseMetadata; import com.google.spanner.admin.instance.v1.AutoscalingConfig; +import com.google.spanner.admin.instance.v1.Instance.Edition; import com.google.spanner.admin.instance.v1.UpdateInstanceMetadata; import java.util.Map; @@ -111,6 +112,12 @@ public Builder putAllLabels(Map labels) { return this; } + @Override + public Builder setEdition(Edition edition) { + infoBuilder.setEdition(edition); + return this; + } + @Override public Instance build() { return new Instance(this); @@ -228,6 +235,7 @@ static Instance fromProto( .setCreateTime(Timestamp.fromProto(proto.getCreateTime())) .setUpdateTime(Timestamp.fromProto(proto.getUpdateTime())) .setAutoscalingConfig(proto.getAutoscalingConfig()) + .setEdition(proto.getEdition()) .setProcessingUnits(proto.getProcessingUnits()); State state; switch (proto.getState()) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java index b672b3b8fa4..2dd70ce108e 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerExceptionFactory.java @@ -16,8 +16,11 @@ package com.google.cloud.spanner; +import static com.google.cloud.spanner.TransactionMutationLimitExceededException.isTransactionMutationLimitException; + import com.google.api.gax.grpc.GrpcStatusCode; import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ErrorDetails; import com.google.api.gax.rpc.WatchdogTimeoutException; import com.google.cloud.spanner.SpannerException.DoNotConstructDirectly; import com.google.common.base.MoreObjects; @@ -256,6 +259,18 @@ private static ErrorInfo extractErrorInfo(Throwable cause) { return null; } + static ErrorDetails extractErrorDetails(Throwable cause) { + Throwable prevCause = null; + while (cause != null && cause != prevCause) { + if (cause instanceof ApiException) { + return ((ApiException) cause).getErrorDetails(); + } + prevCause = cause; + cause = cause.getCause(); + } + return null; + } + /** * Creates a {@link StatusRuntimeException} that contains a {@link RetryInfo} with the specified * retry delay. @@ -313,6 +328,11 @@ static SpannerException newSpannerExceptionPreformatted( token, message, resourceInfo, cause, apiException); } } + case INVALID_ARGUMENT: + if (isTransactionMutationLimitException(cause)) { + return new TransactionMutationLimitExceededException( + token, code, message, cause, apiException); + } // Fall through to the default. default: return new SpannerException( diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionMutationLimitExceededException.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionMutationLimitExceededException.java new file mode 100644 index 00000000000..1b63861bcd1 --- /dev/null +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionMutationLimitExceededException.java @@ -0,0 +1,65 @@ +/* + * Copyright 2024 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 com.google.cloud.spanner.SpannerExceptionFactory.extractErrorDetails; + +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ErrorDetails; +import javax.annotation.Nullable; + +/** Exception thrown by Spanner when the transaction mutation limit has been exceeded. */ +public class TransactionMutationLimitExceededException extends SpannerException { + private static final long serialVersionUID = 1L; + + /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */ + TransactionMutationLimitExceededException( + DoNotConstructDirectly token, + ErrorCode errorCode, + String message, + Throwable cause, + @Nullable ApiException apiException) { + super(token, errorCode, /*retryable = */ false, message, cause, apiException); + } + + static boolean isTransactionMutationLimitException(Throwable cause) { + if (cause == null + || cause.getMessage() == null + || !cause.getMessage().contains("The transaction contains too many mutations.")) { + return false; + } + // Spanner includes a hint that points to the Spanner limits documentation page when the error + // was that the transaction mutation limit was exceeded. We use that here to identify the error, + // as there is no other specific metadata in the error that identifies it (other than the error + // message). + ErrorDetails errorDetails = extractErrorDetails(cause); + if (errorDetails != null && errorDetails.getHelp() != null) { + return errorDetails.getHelp().getLinksCount() == 1 + && errorDetails + .getHelp() + .getLinks(0) + .getDescription() + .equals("Cloud Spanner limits documentation.") + && errorDetails + .getHelp() + .getLinks(0) + .getUrl() + .equals("https://cloud.google.com/spanner/docs/limits"); + } + return false; + } +} diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminSettings.java index cde80bf816e..c94b350914f 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminSettings.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminSettings.java @@ -151,7 +151,7 @@ * RetrySettings.newBuilder() * .setInitialRetryDelayDuration(Duration.ofMillis(500)) * .setRetryDelayMultiplier(1.5) - * .setMaxRetryDelay(Duration.ofMillis(5000)) + * .setMaxRetryDelayDuration(Duration.ofMillis(5000)) * .setTotalTimeoutDuration(Duration.ofHours(24)) * .build()); * databaseAdminSettingsBuilder diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java index 5f292588139..ef84fe2b518 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/admin/database/v1/stub/DatabaseAdminStubSettings.java @@ -104,9 +104,9 @@ import com.google.spanner.admin.database.v1.UpdateDatabaseMetadata; import com.google.spanner.admin.database.v1.UpdateDatabaseRequest; import java.io.IOException; +import java.time.Duration; import java.util.List; import javax.annotation.Generated; -import org.threeten.bp.Duration; // AUTO-GENERATED DOCUMENTATION AND CLASS. /** @@ -175,7 +175,7 @@ * RetrySettings.newBuilder() * .setInitialRetryDelayDuration(Duration.ofMillis(500)) * .setRetryDelayMultiplier(1.5) - * .setMaxRetryDelay(Duration.ofMillis(5000)) + * .setMaxRetryDelayDuration(Duration.ofMillis(5000)) * .setTotalTimeoutDuration(Duration.ofHours(24)) * .build()); * databaseAdminSettingsBuilder @@ -1021,40 +1021,40 @@ public static class Builder extends StubSettings.Builder transactionRetryListeners; protected final boolean excludeTxnFromChangeStreams; protected final RpcPriority rpcPriority; protected final Span span; @@ -110,6 +112,7 @@ abstract static class Builder, T extends AbstractBaseUni private StatementExecutor statementExecutor; private StatementTimeout statementTimeout = new StatementTimeout(); private String transactionTag; + private List transactionRetryListeners; private boolean excludeTxnFromChangeStreams; private RpcPriority rpcPriority; @@ -134,6 +137,16 @@ B setStatementTimeout(StatementTimeout timeout) { return self(); } + B setTransactionRetryListeners(List listeners) { + Preconditions.checkNotNull(listeners); + this.transactionRetryListeners = listeners; + return self(); + } + + boolean hasTransactionRetryListeners() { + return this.transactionRetryListeners != null; + } + B setTransactionTag(@Nullable String tag) { this.transactionTag = tag; return self(); @@ -162,6 +175,7 @@ B setSpan(@Nullable Span span) { this.statementExecutor = builder.statementExecutor; this.statementTimeout = builder.statementTimeout; this.transactionTag = builder.transactionTag; + this.transactionRetryListeners = builder.transactionRetryListeners; this.excludeTxnFromChangeStreams = builder.excludeTxnFromChangeStreams; this.rpcPriority = builder.rpcPriority; this.span = Preconditions.checkNotNull(builder.span); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AutocommitDmlMode.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AutocommitDmlMode.java index 8710bdd01d1..4d6becfe1bd 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AutocommitDmlMode.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AutocommitDmlMode.java @@ -18,8 +18,18 @@ /** Enum used to define the behavior of DML statements in autocommit mode */ public enum AutocommitDmlMode { + /** TRANSACTIONAL: DML statements use a standard atomic transaction. */ TRANSACTIONAL, - PARTITIONED_NON_ATOMIC; + /** PARTITIONED_NON_ATOMIC: DML statements use a Partitioned DML transaction. */ + PARTITIONED_NON_ATOMIC, + /** + * TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC: DML statements are first executed with a + * standard atomic transaction. If that fails due to the mutation limit being exceeded, the + * statement will automatically be retried using a Partitioned DML transaction. These statements + * are not guaranteed to be atomic. The corresponding {@link TransactionRetryListener} methods + * will be invoked when a DML statement falls back to Partitioned DML. + */ + TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC; private final String statementString; 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 37dcd3f9aac..0b2d0b6b3a0 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 @@ -2125,6 +2125,7 @@ UnitOfWork createNewUnitOfWork( .setReadOnly(getConnectionPropertyValue(READONLY)) .setReadOnlyStaleness(getConnectionPropertyValue(READ_ONLY_STALENESS)) .setAutocommitDmlMode(getConnectionPropertyValue(AUTOCOMMIT_DML_MODE)) + .setTransactionRetryListeners(transactionRetryListeners) .setReturnCommitStats(getConnectionPropertyValue(RETURN_COMMIT_STATS)) .setExcludeTxnFromChangeStreams(excludeTxnFromChangeStreams) .setMaxCommitDelay(getConnectionPropertyValue(MAX_COMMIT_DELAY)) 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 e174a73b701..4ae0ae00608 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 @@ -153,7 +153,6 @@ class ReadWriteTransaction extends AbstractMultiUseTransaction { private final SavepointSupport savepointSupport; private int transactionRetryAttempts; private int successfulRetries; - private final List transactionRetryListeners; private volatile ApiFuture txContextFuture; private boolean canUseSingleUseRead; private volatile SettableApiFuture commitResponseFuture; @@ -203,7 +202,6 @@ static class Builder extends AbstractMultiUseTransaction.Builder transactionRetryListeners; private Builder() {} @@ -253,19 +251,13 @@ Builder setSavepointSupport(SavepointSupport savepointSupport) { return this; } - Builder setTransactionRetryListeners(List listeners) { - Preconditions.checkNotNull(listeners); - this.transactionRetryListeners = listeners; - return this; - } - @Override ReadWriteTransaction build() { Preconditions.checkState(dbClient != null, "No DatabaseClient client specified"); Preconditions.checkState( retryAbortsInternally != null, "RetryAbortsInternally is not specified"); Preconditions.checkState( - transactionRetryListeners != null, "TransactionRetryListeners are not specified"); + hasTransactionRetryListeners(), "TransactionRetryListeners are not specified"); Preconditions.checkState(savepointSupport != null, "SavepointSupport is not specified"); return new ReadWriteTransaction(this); } @@ -301,7 +293,6 @@ private ReadWriteTransaction(Builder builder) { this.keepAliveLock = this.keepTransactionAlive ? new ReentrantLock() : null; this.retryAbortsInternally = builder.retryAbortsInternally; this.savepointSupport = builder.savepointSupport; - this.transactionRetryListeners = builder.transactionRetryListeners; this.transactionOptions = extractOptions(builder); } 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 53a1bb03b10..3c533cb9a7a 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 @@ -20,6 +20,7 @@ import static com.google.cloud.spanner.connection.AbstractStatementParser.RUN_BATCH_STATEMENT; import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutureCallback; import com.google.api.core.ApiFutures; import com.google.api.core.SettableApiFuture; import com.google.api.gax.longrunning.OperationFuture; @@ -42,11 +43,10 @@ import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.cloud.spanner.TimestampBound; +import com.google.cloud.spanner.TransactionMutationLimitExceededException; 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.AbstractStatementParser.StatementType; -import com.google.cloud.spanner.connection.ReadWriteTransaction.Builder; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -56,6 +56,7 @@ import io.opentelemetry.context.Scope; import java.time.Duration; import java.util.Arrays; +import java.util.UUID; import java.util.concurrent.Callable; import javax.annotation.Nonnull; @@ -219,6 +220,11 @@ public boolean supportsDirectedReads(ParsedStatement parsedStatement) { return parsedStatement.isQuery(); } + private boolean isRetryDmlAsPartitionedDml() { + return this.autocommitDmlMode + == AutocommitDmlMode.TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC; + } + private void checkAndMarkUsed() { Preconditions.checkState(!used, "This single-use transaction has already been used"); used = true; @@ -434,6 +440,7 @@ public ApiFuture executeUpdateAsync( ApiFuture res; switch (autocommitDmlMode) { case TRANSACTIONAL: + case TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC: res = ApiFutures.transform( executeTransactionalUpdateAsync(callType, update, AnalyzeMode.NONE, options), @@ -561,11 +568,89 @@ private ApiFuture> executeTransactionalUpdateAsync( throw t; } }; - return executeStatementAsync( - callType, - update, - callable, - ImmutableList.of(SpannerGrpc.getExecuteSqlMethod(), SpannerGrpc.getCommitMethod())); + ApiFuture> transactionalResult = + executeStatementAsync( + callType, + update, + callable, + ImmutableList.of(SpannerGrpc.getExecuteSqlMethod(), SpannerGrpc.getCommitMethod())); + // Retry as Partitioned DML if the statement fails due to exceeding the mutation limit if that + // option has been enabled. + if (isRetryDmlAsPartitionedDml()) { + return addRetryUpdateAsPartitionedDmlCallback(transactionalResult, callType, update, options); + } + return transactionalResult; + } + + /** + * Adds a callback to the given future that retries the update statement using Partitioned DML if + * the original statement fails with a {@link TransactionMutationLimitExceededException}. + */ + private ApiFuture> addRetryUpdateAsPartitionedDmlCallback( + ApiFuture> transactionalResult, + CallType callType, + final ParsedStatement update, + final UpdateOption... options) { + // Catch TransactionMutationLimitExceededException and retry as Partitioned DML. All other + // exceptions are just propagated. + return ApiFutures.catchingAsync( + transactionalResult, + TransactionMutationLimitExceededException.class, + mutationLimitExceededException -> { + UUID executionId = UUID.randomUUID(); + // Invoke the retryDmlAsPartitionedDmlStarting method for the TransactionRetryListeners + // that have been registered for the connection. + for (TransactionRetryListener listener : this.transactionRetryListeners) { + listener.retryDmlAsPartitionedDmlStarting( + executionId, update.getStatement(), mutationLimitExceededException); + } + // Try to execute the DML statement as Partitioned DML. + ApiFuture> partitionedResult = + ApiFutures.transform( + executePartitionedUpdateAsync(callType, update, options), + lowerBoundUpdateCount -> Tuple.of(lowerBoundUpdateCount, null), + MoreExecutors.directExecutor()); + + // Add a callback to the future that invokes the TransactionRetryListeners after the + // Partitioned DML statement finished. This will invoke either the Finished or Failed + // method on the listeners. + ApiFutures.addCallback( + partitionedResult, + new ApiFutureCallback>() { + @Override + public void onFailure(Throwable throwable) { + for (TransactionRetryListener listener : + SingleUseTransaction.this.transactionRetryListeners) { + listener.retryDmlAsPartitionedDmlFailed( + executionId, update.getStatement(), throwable); + } + } + + @Override + public void onSuccess(Tuple result) { + for (TransactionRetryListener listener : + SingleUseTransaction.this.transactionRetryListeners) { + listener.retryDmlAsPartitionedDmlFinished( + executionId, update.getStatement(), result.x()); + } + } + }, + MoreExecutors.directExecutor()); + + // Catch any exception from the Partitioned DML execution and throw the original + // TransactionMutationLimitExceededException instead. + // The exception that is returned for the Partitioned DML statement is added to the + // exception as a suppressed exception. + return ApiFutures.catching( + partitionedResult, + Throwable.class, + input -> { + mutationLimitExceededException.addSuppressed(input); + throw mutationLimitExceededException; + }, + MoreExecutors.directExecutor()); + }, + MoreExecutors.directExecutor()); } private ApiFuture analyzeTransactionalUpdateAsync( diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/TransactionRetryListener.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/TransactionRetryListener.java index d622d8fde36..ba2613ffd86 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/TransactionRetryListener.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/TransactionRetryListener.java @@ -20,6 +20,9 @@ import com.google.cloud.Timestamp; import com.google.cloud.spanner.AbortedDueToConcurrentModificationException; import com.google.cloud.spanner.AbortedException; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.TransactionMutationLimitExceededException; +import java.util.UUID; /** * Cloud Spanner can abort any read/write transaction because of potential deadlocks or other @@ -87,4 +90,42 @@ void retryFinished( long transactionId, int retryAttempt, TransactionRetryListener.RetryResult result); + + /** + * This method is called when an atomic DML statement is retried as a Partitioned DML statement. + * + * @param executionId a generated, unique ID for this execution. The same ID is passed in to the + * methods {@link #retryDmlAsPartitionedDmlFinished(UUID, Statement, long)} and {@link + * #retryDmlAsPartitionedDmlFailed(UUID, Statement, Throwable)} when the execution finishes or + * fails. + * @param statement the statement that is being retried as Partitioned DML + * @param exception the mutation-limit-exceeded exception that was returned by Spanner during the + * initial execution. + */ + default void retryDmlAsPartitionedDmlStarting( + UUID executionId, Statement statement, TransactionMutationLimitExceededException exception) {} + + /** + * This method is called when an atomic DML statement has been successfully retried as a + * Partitioned DML statement. + * + * @param executionId the unique ID of this statement execution + * @param statement the statement that was successfully retried as Partitioned DML + * @param lowerBoundUpdateCount the lower-bound update count returned by Spanner after executing + * the statement as Partitioned DML + */ + default void retryDmlAsPartitionedDmlFinished( + UUID executionId, Statement statement, long lowerBoundUpdateCount) {} + + /** + * This method is called when an atomic DML statement failed to be retried as a Partitioned DML + * statement. + * + * @param executionId the unique ID of this statement execution + * @param statement the statement that failed to be retried as Partitioned DML + * @param exception the exception that was returned when the statement was executed as Partitioned + * DML + */ + default void retryDmlAsPartitionedDmlFailed( + UUID executionId, Statement statement, Throwable exception) {} } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/TransactionRetryListenerImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/TransactionRetryListenerImpl.java new file mode 100644 index 00000000000..42497564b95 --- /dev/null +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/TransactionRetryListenerImpl.java @@ -0,0 +1,45 @@ +/* + * Copyright 2024 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.Timestamp; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.TransactionMutationLimitExceededException; +import java.util.UUID; + +/** Default (no-op) implementation for {@link TransactionRetryListener}. */ +public abstract class TransactionRetryListenerImpl implements TransactionRetryListener { + + @Override + public void retryStarting(Timestamp transactionStarted, long transactionId, int retryAttempt) {} + + @Override + public void retryFinished( + Timestamp transactionStarted, long transactionId, int retryAttempt, RetryResult result) {} + + @Override + public void retryDmlAsPartitionedDmlStarting( + UUID executionId, Statement statement, TransactionMutationLimitExceededException exception) {} + + @Override + public void retryDmlAsPartitionedDmlFinished( + UUID executionId, Statement statement, long lowerBoundUpdateCount) {} + + @Override + public void retryDmlAsPartitionedDmlFailed( + UUID executionId, Statement statement, Throwable exception) {} +} diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java index 8625c17785a..3cb3c7c4cc6 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/SpannerClient.java @@ -1210,6 +1210,7 @@ public final UnaryCallable deleteSessionCallable() * .setRequestOptions(RequestOptions.newBuilder().build()) * .setDirectedReadOptions(DirectedReadOptions.newBuilder().build()) * .setDataBoostEnabled(true) + * .setLastStatement(true) * .build(); * ResultSet response = spannerClient.executeSql(request); * } @@ -1259,6 +1260,7 @@ public final ResultSet executeSql(ExecuteSqlRequest request) { * .setRequestOptions(RequestOptions.newBuilder().build()) * .setDirectedReadOptions(DirectedReadOptions.newBuilder().build()) * .setDataBoostEnabled(true) + * .setLastStatement(true) * .build(); * ApiFuture future = spannerClient.executeSqlCallable().futureCall(request); * // Do something. @@ -1301,6 +1303,7 @@ public final UnaryCallable executeSqlCallable() { * .setRequestOptions(RequestOptions.newBuilder().build()) * .setDirectedReadOptions(DirectedReadOptions.newBuilder().build()) * .setDataBoostEnabled(true) + * .setLastStatement(true) * .build(); * ServerStream stream = * spannerClient.executeStreamingSqlCallable().call(request); @@ -1345,6 +1348,7 @@ public final UnaryCallable executeSqlCallable() { * .addAllStatements(new ArrayList()) * .setSeqno(109325920) * .setRequestOptions(RequestOptions.newBuilder().build()) + * .setLastStatements(true) * .build(); * ExecuteBatchDmlResponse response = spannerClient.executeBatchDml(request); * } @@ -1387,6 +1391,7 @@ public final ExecuteBatchDmlResponse executeBatchDml(ExecuteBatchDmlRequest requ * .addAllStatements(new ArrayList()) * .setSeqno(109325920) * .setRequestOptions(RequestOptions.newBuilder().build()) + * .setLastStatements(true) * .build(); * ApiFuture future = * spannerClient.executeBatchDmlCallable().futureCall(request); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java index ae4b1c11daf..004f1e09756 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/v1/stub/SpannerStubSettings.java @@ -75,9 +75,9 @@ import com.google.spanner.v1.Session; import com.google.spanner.v1.Transaction; import java.io.IOException; +import java.time.Duration; import java.util.List; import javax.annotation.Generated; -import org.threeten.bp.Duration; // AUTO-GENERATED DOCUMENTATION AND CLASS. /** @@ -484,43 +484,43 @@ public static class Builder extends StubSettings.Builder> expectedRequests = + ImmutableList> expectedRequests = ImmutableList.of( BatchCreateSessionsRequest.class, // The first update that fails. This will cause a transaction retry. @@ -671,7 +671,7 @@ public void asyncTransactionManagerFireAndForgetInvalidBatchUpdate() throws Exce } } } - ImmutableList> expectedRequests = + ImmutableList> expectedRequests = ImmutableList.of( BatchCreateSessionsRequest.class, ExecuteBatchDmlRequest.class, @@ -714,7 +714,7 @@ public void asyncTransactionManagerBatchUpdateAborted() throws Exception { assertThat(attempt.get()).isEqualTo(2); // There should only be 1 CommitRequest, as the first attempt should abort already after the // ExecuteBatchDmlRequest. - ImmutableList> expectedRequests = + ImmutableList> expectedRequests = ImmutableList.of( BatchCreateSessionsRequest.class, ExecuteBatchDmlRequest.class, @@ -756,7 +756,7 @@ public void asyncTransactionManagerBatchUpdateAbortedBeforeFirstStatement() thro assertThat(attempt.get()).isEqualTo(2); // There should only be 1 CommitRequest, as the first attempt should abort already after the // ExecuteBatchDmlRequest. - ImmutableList> expectedRequests = + ImmutableList> expectedRequests = ImmutableList.of( BatchCreateSessionsRequest.class, ExecuteBatchDmlRequest.class, @@ -816,7 +816,7 @@ public void asyncTransactionManagerWithBatchUpdateCommitAborted() throws Excepti } finally { mockSpanner.putStatementResult(StatementResult.update(UPDATE_STATEMENT, UPDATE_COUNT)); } - ImmutableList> expectedRequests = + ImmutableList> expectedRequests = ImmutableList.of( BatchCreateSessionsRequest.class, ExecuteBatchDmlRequest.class, @@ -914,7 +914,7 @@ public void asyncTransactionManagerWithBatchUpdateCommitFails() { assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); assertThat(e.getMessage()).contains("mutation limit exceeded"); } - ImmutableList> expectedRequests = + ImmutableList> expectedRequests = ImmutableList.of( BatchCreateSessionsRequest.class, ExecuteBatchDmlRequest.class, CommitRequest.class); if (isMultiplexedSessionsEnabled()) { @@ -945,7 +945,7 @@ public void asyncTransactionManagerWaitsUntilAsyncBatchUpdateHasFinished() throw } } } - ImmutableList> expectedRequests = + ImmutableList> expectedRequests = ImmutableList.of( BatchCreateSessionsRequest.class, ExecuteBatchDmlRequest.class, CommitRequest.class); if (isMultiplexedSessionsEnabled()) { diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RetryDmlAsPartitionedDmlMockServerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RetryDmlAsPartitionedDmlMockServerTest.java new file mode 100644 index 00000000000..022c9a92f1f --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/RetryDmlAsPartitionedDmlMockServerTest.java @@ -0,0 +1,216 @@ +/* + * Copyright 2024 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +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; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.SpannerException; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.TransactionMutationLimitExceededException; +import com.google.protobuf.Any; +import com.google.rpc.Help; +import com.google.rpc.Help.Link; +import com.google.spanner.v1.BeginTransactionRequest; +import com.google.spanner.v1.CommitRequest; +import com.google.spanner.v1.ExecuteSqlRequest; +import io.grpc.Metadata; +import io.grpc.Status; +import io.grpc.StatusRuntimeException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class RetryDmlAsPartitionedDmlMockServerTest extends AbstractMockServerTest { + + static StatusRuntimeException createTransactionMutationLimitExceededException() { + Metadata.Key key = + Metadata.Key.of("grpc-status-details-bin", Metadata.BINARY_BYTE_MARSHALLER); + Help help = + Help.newBuilder() + .addLinks( + Link.newBuilder() + .setDescription("Cloud Spanner limits documentation.") + .setUrl("https://cloud.google.com/spanner/docs/limits") + .build()) + .build(); + com.google.rpc.Status status = + com.google.rpc.Status.newBuilder().addDetails(Any.pack(help)).build(); + + Metadata trailers = new Metadata(); + trailers.put(key, status.toByteArray()); + + return Status.INVALID_ARGUMENT + .withDescription("The transaction contains too many mutations.") + .asRuntimeException(trailers); + } + + @Test + public void testTransactionMutationLimitExceeded_isNotRetriedByDefault() { + mockSpanner.setExecuteSqlExecutionTime( + SimulatedExecutionTime.ofException(createTransactionMutationLimitExceededException())); + + try (Connection connection = createConnection()) { + connection.setAutocommit(true); + assertEquals(AutocommitDmlMode.TRANSACTIONAL, connection.getAutocommitDmlMode()); + + TransactionMutationLimitExceededException exception = + assertThrows( + TransactionMutationLimitExceededException.class, + () -> connection.executeUpdate(Statement.of("update test set value=1 where true"))); + assertEquals(0, exception.getSuppressed().length); + } + assertEquals(1, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + assertEquals(0, mockSpanner.countRequestsOfType(CommitRequest.class)); + } + + @Test + public void testTransactionMutationLimitExceeded_canBeRetriedAsPDML() { + Statement statement = Statement.of("update test set value=1 where true"); + mockSpanner.setExecuteSqlExecutionTime( + SimulatedExecutionTime.ofException(createTransactionMutationLimitExceededException())); + mockSpanner.putStatementResult( + MockSpannerServiceImpl.StatementResult.update(statement, 100000L)); + + try (Connection connection = createConnection()) { + connection.setAutocommit(true); + connection.setAutocommitDmlMode( + AutocommitDmlMode.TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC); + + long updateCount = connection.executeUpdate(statement); + assertEquals(100000L, updateCount); + } + // Verify that the request is retried as Partitioned DML. + assertEquals(2, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + // The transactional request uses inline-begin. + ExecuteSqlRequest transactionalRequest = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0); + assertTrue(transactionalRequest.getTransaction().getBegin().hasReadWrite()); + + // Partitioned DML uses an explicit BeginTransaction RPC. + assertEquals(1, mockSpanner.countRequestsOfType(BeginTransactionRequest.class)); + BeginTransactionRequest beginRequest = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class).get(0); + assertTrue(beginRequest.getOptions().hasPartitionedDml()); + ExecuteSqlRequest partitionedDmlRequest = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(1); + assertTrue(partitionedDmlRequest.getTransaction().hasId()); + + // Partitioned DML transactions are not committed. + assertEquals(0, mockSpanner.countRequestsOfType(CommitRequest.class)); + } + + @Test + public void testTransactionMutationLimitExceeded_retryAsPDMLFails() { + Statement statement = Statement.of("insert into test (id, value) select -id, value from test"); + // The transactional update statement uses ExecuteSql(..). + mockSpanner.setExecuteSqlExecutionTime( + SimulatedExecutionTime.ofException(createTransactionMutationLimitExceededException())); + mockSpanner.putStatementResult( + MockSpannerServiceImpl.StatementResult.exception( + statement, + Status.INVALID_ARGUMENT + .withDescription("This statement is not supported with Partitioned DML") + .asRuntimeException())); + + try (Connection connection = createConnection()) { + connection.setAutocommit(true); + connection.setAutocommitDmlMode( + AutocommitDmlMode.TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC); + + // The connection throws TransactionMutationLimitExceededException if the retry using + // partitioned DML fails. The exception from the failed retry is returned as a suppressed + // exception of the TransactionMutationLimitExceededException. + TransactionMutationLimitExceededException exception = + assertThrows( + TransactionMutationLimitExceededException.class, + () -> connection.executeUpdate(statement)); + assertEquals(1, exception.getSuppressed().length); + assertEquals(SpannerException.class, exception.getSuppressed()[0].getClass()); + SpannerException spannerException = (SpannerException) exception.getSuppressed()[0]; + assertEquals(ErrorCode.INVALID_ARGUMENT, spannerException.getErrorCode()); + assertTrue( + spannerException.getMessage(), + spannerException + .getMessage() + .contains("This statement is not supported with Partitioned DML")); + } + // Verify that the request was retried as Partitioned DML. + assertEquals(2, mockSpanner.countRequestsOfType(ExecuteSqlRequest.class)); + // The transactional request uses inline-begin. + ExecuteSqlRequest transactionalRequest = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(0); + assertTrue(transactionalRequest.getTransaction().getBegin().hasReadWrite()); + + // Partitioned DML uses an explicit BeginTransaction RPC. + assertEquals(1, mockSpanner.countRequestsOfType(BeginTransactionRequest.class)); + BeginTransactionRequest beginRequest = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class).get(0); + assertTrue(beginRequest.getOptions().hasPartitionedDml()); + ExecuteSqlRequest partitionedDmlRequest = + mockSpanner.getRequestsOfType(ExecuteSqlRequest.class).get(1); + assertTrue(partitionedDmlRequest.getTransaction().hasId()); + + // Partitioned DML transactions are not committed. + assertEquals(0, mockSpanner.countRequestsOfType(CommitRequest.class)); + } + + @Test + public void testSqlStatements() { + for (Dialect dialect : Dialect.values()) { + SpannerPool.closeSpannerPool(); + mockSpanner.putStatementResult( + MockSpannerServiceImpl.StatementResult.detectDialectResult(dialect)); + String prefix = dialect == Dialect.POSTGRESQL ? "SPANNER." : ""; + + try (Connection connection = createConnection()) { + connection.setAutocommit(true); + try (ResultSet resultSet = + connection.executeQuery( + Statement.of(String.format("show variable %sautocommit_dml_mode", prefix)))) { + assertTrue(resultSet.next()); + assertEquals( + AutocommitDmlMode.TRANSACTIONAL.name(), + resultSet.getString(String.format("%sAUTOCOMMIT_DML_MODE", prefix))); + assertFalse(resultSet.next()); + } + connection.execute( + Statement.of( + String.format( + "set %sautocommit_dml_mode = 'transactional_with_fallback_to_partitioned_non_atomic'", + prefix))); + try (ResultSet resultSet = + connection.executeQuery( + Statement.of(String.format("show variable %sautocommit_dml_mode", prefix)))) { + assertTrue(resultSet.next()); + assertEquals( + AutocommitDmlMode.TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC.name(), + resultSet.getString(String.format("%sAUTOCOMMIT_DML_MODE", prefix))); + assertFalse(resultSet.next()); + } + } + } + } +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITRetryDmlAsPartitionedDmlTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITRetryDmlAsPartitionedDmlTest.java new file mode 100644 index 00000000000..4a7c2ce26c1 --- /dev/null +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITRetryDmlAsPartitionedDmlTest.java @@ -0,0 +1,192 @@ +/* + * Copyright 2024 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.it; + +import static com.google.cloud.spanner.testing.EmulatorSpannerHelper.isUsingEmulator; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; + +import com.google.api.core.SettableApiFuture; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.ErrorCode; +import com.google.cloud.spanner.Mutation; +import com.google.cloud.spanner.ParallelIntegrationTest; +import com.google.cloud.spanner.SpannerException; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.TransactionMutationLimitExceededException; +import com.google.cloud.spanner.connection.AutocommitDmlMode; +import com.google.cloud.spanner.connection.Connection; +import com.google.cloud.spanner.connection.ITAbstractSpannerTest; +import com.google.cloud.spanner.connection.TransactionRetryListenerImpl; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@Category(ParallelIntegrationTest.class) +@RunWith(JUnit4.class) +public class ITRetryDmlAsPartitionedDmlTest extends ITAbstractSpannerTest { + private static final int NUM_ROWS = 100000; + + @BeforeClass + public static void setup() { + // This shadows the setup() method in the super class and prevents it from being executed. + // That allows us to have a custom setup method in this class. + } + + @BeforeClass + public static void setupTestData() { + assumeFalse("The emulator does not enforce the mutation limit", isUsingEmulator()); + + database = + env.getTestHelper() + .createTestDatabase( + "CREATE TABLE TEST (ID INT64 NOT NULL, NAME STRING(100) NOT NULL) PRIMARY KEY (ID)"); + DatabaseClient client = env.getTestHelper().getClient().getDatabaseClient(database.getId()); + int rowsCreated = 0; + int batchSize = 5000; + while (rowsCreated < NUM_ROWS) { + List mutations = new ArrayList<>(batchSize); + for (int row = rowsCreated; row < rowsCreated + batchSize; row++) { + mutations.add( + Mutation.newInsertOrUpdateBuilder("TEST") + .set("id") + .to(row) + .set("name") + .to("Row " + row) + .build()); + } + client.writeAtLeastOnce(mutations); + rowsCreated += batchSize; + } + } + + @Test + public void testDmlFailsIfMutationLimitExceeded() { + try (Connection connection = createConnection()) { + connection.setAutocommit(true); + assertThrows( + TransactionMutationLimitExceededException.class, + () -> + connection.executeUpdate( + Statement.of("update test set name=name || ' - updated' where true"))); + } + } + + @Test + public void testRetryDmlAsPartitionedDml() throws Exception { + try (Connection connection = createConnection()) { + connection.setAutocommit(true); + connection.setAutocommitDmlMode( + AutocommitDmlMode.TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC); + + // Set up a listener that gets a callback when a DML statement is retried as Partitioned DML. + SettableApiFuture startExecutionIdFuture = SettableApiFuture.create(); + SettableApiFuture finishedExecutionIdFuture = SettableApiFuture.create(); + SettableApiFuture lowerBoundUpdateCountFuture = SettableApiFuture.create(); + connection.addTransactionRetryListener( + new TransactionRetryListenerImpl() { + @Override + public void retryDmlAsPartitionedDmlStarting( + UUID executionId, + Statement statement, + TransactionMutationLimitExceededException exception) { + startExecutionIdFuture.set(executionId); + } + + @Override + public void retryDmlAsPartitionedDmlFinished( + UUID executionId, Statement statement, long updateCount) { + finishedExecutionIdFuture.set(executionId); + lowerBoundUpdateCountFuture.set(updateCount); + } + }); + + long updateCount = + connection.executeUpdate( + Statement.of("update test set name=name || ' - updated' where true")); + assertEquals(NUM_ROWS, updateCount); + assertEquals( + startExecutionIdFuture.get(1, TimeUnit.SECONDS), + finishedExecutionIdFuture.get(1, TimeUnit.SECONDS)); + assertEquals(updateCount, lowerBoundUpdateCountFuture.get(1, TimeUnit.SECONDS).longValue()); + } + } + + @Test + public void testRetryDmlAsPartitionedDml_failsForLargeInserts() throws Exception { + try (Connection connection = createConnection()) { + connection.setAutocommit(true); + connection.setAutocommitDmlMode( + AutocommitDmlMode.TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC); + + // Set up a listener that gets a callback when a DML statement is retried as Partitioned DML. + SettableApiFuture startExecutionIdFuture = SettableApiFuture.create(); + SettableApiFuture failedExecutionIdFuture = SettableApiFuture.create(); + SettableApiFuture executionExceptionFuture = SettableApiFuture.create(); + connection.addTransactionRetryListener( + new TransactionRetryListenerImpl() { + @Override + public void retryDmlAsPartitionedDmlStarting( + UUID executionId, + Statement statement, + TransactionMutationLimitExceededException exception) { + startExecutionIdFuture.set(executionId); + } + + @Override + public void retryDmlAsPartitionedDmlFailed( + UUID executionId, Statement statement, Throwable exception) { + failedExecutionIdFuture.set(executionId); + executionExceptionFuture.set(exception); + } + }); + + // Note that the executeUpdate method throws the original + // TransactionMutationLimitExceededException, and not the exception that is thrown when the + // statement is retried as Partitioned DML. + TransactionMutationLimitExceededException mutationLimitExceededException = + assertThrows( + TransactionMutationLimitExceededException.class, + () -> + connection.executeUpdate( + Statement.of("insert into test (id, name) select -id, name from test"))); + assertEquals( + startExecutionIdFuture.get(1, TimeUnit.SECONDS), + failedExecutionIdFuture.get(1, TimeUnit.SECONDS)); + Throwable executionException = executionExceptionFuture.get(1L, TimeUnit.SECONDS); + assertEquals(SpannerException.class, executionException.getClass()); + SpannerException spannerException = (SpannerException) executionException; + // Verify that this exception indicates that the INSERT statement could not be executed as + // Partitioned DML. + assertEquals(ErrorCode.INVALID_ARGUMENT, spannerException.getErrorCode()); + assertTrue( + spannerException.getMessage(), + spannerException.getMessage().contains("INSERT is not supported for Partitioned DML.")); + assertEquals(1, mutationLimitExceededException.getSuppressed().length); + assertSame(spannerException, mutationLimitExceededException.getSuppressed()[0]); + } + } +} diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientHttpJsonTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientHttpJsonTest.java index 1683d533855..ae1cfdc8a8a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientHttpJsonTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientHttpJsonTest.java @@ -607,6 +607,7 @@ public void executeSqlTest() throws Exception { .setRequestOptions(RequestOptions.newBuilder().build()) .setDirectedReadOptions(DirectedReadOptions.newBuilder().build()) .setDataBoostEnabled(true) + .setLastStatement(true) .build(); ResultSet actualResponse = client.executeSql(request); @@ -650,6 +651,7 @@ public void executeSqlExceptionTest() throws Exception { .setRequestOptions(RequestOptions.newBuilder().build()) .setDirectedReadOptions(DirectedReadOptions.newBuilder().build()) .setDataBoostEnabled(true) + .setLastStatement(true) .build(); client.executeSql(request); Assert.fail("No exception raised"); @@ -687,6 +689,7 @@ public void executeBatchDmlTest() throws Exception { .addAllStatements(new ArrayList()) .setSeqno(109325920) .setRequestOptions(RequestOptions.newBuilder().build()) + .setLastStatements(true) .build(); ExecuteBatchDmlResponse actualResponse = client.executeBatchDml(request); @@ -723,6 +726,7 @@ public void executeBatchDmlExceptionTest() throws Exception { .addAllStatements(new ArrayList()) .setSeqno(109325920) .setRequestOptions(RequestOptions.newBuilder().build()) + .setLastStatements(true) .build(); client.executeBatchDml(request); Assert.fail("No exception raised"); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientTest.java index 83caf7405d9..e0e1251d1d2 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/v1/SpannerClientTest.java @@ -565,6 +565,7 @@ public void executeSqlTest() throws Exception { .setRequestOptions(RequestOptions.newBuilder().build()) .setDirectedReadOptions(DirectedReadOptions.newBuilder().build()) .setDataBoostEnabled(true) + .setLastStatement(true) .build(); ResultSet actualResponse = client.executeSql(request); @@ -587,6 +588,7 @@ public void executeSqlTest() throws Exception { Assert.assertEquals(request.getRequestOptions(), actualRequest.getRequestOptions()); Assert.assertEquals(request.getDirectedReadOptions(), actualRequest.getDirectedReadOptions()); Assert.assertEquals(request.getDataBoostEnabled(), actualRequest.getDataBoostEnabled()); + Assert.assertEquals(request.getLastStatement(), actualRequest.getLastStatement()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -614,6 +616,7 @@ public void executeSqlExceptionTest() throws Exception { .setRequestOptions(RequestOptions.newBuilder().build()) .setDirectedReadOptions(DirectedReadOptions.newBuilder().build()) .setDataBoostEnabled(true) + .setLastStatement(true) .build(); client.executeSql(request); Assert.fail("No exception raised"); @@ -649,6 +652,7 @@ public void executeStreamingSqlTest() throws Exception { .setRequestOptions(RequestOptions.newBuilder().build()) .setDirectedReadOptions(DirectedReadOptions.newBuilder().build()) .setDataBoostEnabled(true) + .setLastStatement(true) .build(); MockStreamObserver responseObserver = new MockStreamObserver<>(); @@ -681,6 +685,7 @@ public void executeStreamingSqlExceptionTest() throws Exception { .setRequestOptions(RequestOptions.newBuilder().build()) .setDirectedReadOptions(DirectedReadOptions.newBuilder().build()) .setDataBoostEnabled(true) + .setLastStatement(true) .build(); MockStreamObserver responseObserver = new MockStreamObserver<>(); @@ -717,6 +722,7 @@ public void executeBatchDmlTest() throws Exception { .addAllStatements(new ArrayList()) .setSeqno(109325920) .setRequestOptions(RequestOptions.newBuilder().build()) + .setLastStatements(true) .build(); ExecuteBatchDmlResponse actualResponse = client.executeBatchDml(request); @@ -731,6 +737,7 @@ public void executeBatchDmlTest() throws Exception { Assert.assertEquals(request.getStatementsList(), actualRequest.getStatementsList()); Assert.assertEquals(request.getSeqno(), actualRequest.getSeqno()); Assert.assertEquals(request.getRequestOptions(), actualRequest.getRequestOptions()); + Assert.assertEquals(request.getLastStatements(), actualRequest.getLastStatements()); Assert.assertTrue( channelProvider.isHeaderSent( ApiClientHeaderProvider.getDefaultApiClientHeaderKey(), @@ -751,6 +758,7 @@ public void executeBatchDmlExceptionTest() throws Exception { .addAllStatements(new ArrayList()) .setSeqno(109325920) .setRequestOptions(RequestOptions.newBuilder().build()) + .setLastStatements(true) .build(); client.executeBatchDml(request); Assert.fail("No exception raised"); 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 2a63d9b3faf..552e75f1097 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 @@ -10291,6 +10291,204 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT set/-autocommit_dml_mode='TRANSACTIONAL'; NEW_CONNECTION; +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set autocommit_dml_mode='transactional_with_fallback_to_partitioned_non_atomic'; +NEW_CONNECTION; + set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; + set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; + + + +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' ; +NEW_CONNECTION; +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' ; +NEW_CONNECTION; +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' + +; +NEW_CONNECTION; +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set +autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +foo set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' bar; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +%set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'%; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set%autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +_set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'_; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set_autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +&set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'&; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set&autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +$set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'$; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set$autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +@set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'@; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set@autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +!set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'!; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set!autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +*set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'*; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set*autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +(set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'(; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set(autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +)set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'); +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set)autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +-set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'-; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set-autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT ++set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'+; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set+autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +-#set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'-#; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set-#autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +/set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'/; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set/autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +\set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'\; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set\autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +?set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'?; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set?autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +-/set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'-/; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set-/autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +/#set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'/#; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set/#autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +/-set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'/-; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set/-autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; set statement_timeout=null; NEW_CONNECTION; SET STATEMENT_TIMEOUT=NULL; 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 b693a70a0c9..5985ba92479 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 @@ -160,15 +160,15 @@ NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:27.550000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:27.550000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.066000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.066000000Z' 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 2024-10-11T16:42:27.550000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.066000000Z'; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -510,15 +510,15 @@ NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:27.692000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:27.692000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.187000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.187000000Z' 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 2024-10-11T16:42:27.692000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.187000000Z'; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -950,8 +950,8 @@ BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; ROLLBACK; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:27.809000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:27.809000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.294000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.294000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; @@ -961,7 +961,7 @@ BEGIN TRANSACTION; SELECT 1 AS TEST; ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:27.809000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.294000000Z'; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -1462,8 +1462,8 @@ BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:27.921000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:27.921000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.413000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.413000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; @@ -1473,7 +1473,7 @@ BEGIN TRANSACTION; SELECT 1 AS TEST; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:27.921000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.413000000Z'; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -1876,15 +1876,15 @@ NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.018000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.018000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.523000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.523000000Z' 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 2024-10-11T16:42:28.018000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.523000000Z'; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -2243,14 +2243,14 @@ SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.103000000Z'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.613000000Z'; 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 2024-10-11T16:42:28.103000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.613000000Z'; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -2600,13 +2600,13 @@ SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.198000000Z'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.705000000Z'; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.198000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.705000000Z'; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -2910,14 +2910,14 @@ SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.286000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.286000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.790000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.790000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.286000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.790000000Z'; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -3245,15 +3245,15 @@ NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.382000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.382000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.890000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.890000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.382000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.890000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -3662,8 +3662,8 @@ 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 2024-10-11T16:42:28.470000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.470000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.965000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.965000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -3672,7 +3672,7 @@ 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 2024-10-11T16:42:28.470000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.965000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -4081,14 +4081,14 @@ 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='READ_TIMESTAMP 2024-10-11T16:42:28.556000000Z'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.043000000Z'; NEW_CONNECTION; SET READONLY=FALSE; 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='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.556000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.043000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -4438,13 +4438,13 @@ SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.640000000Z'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.113000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.640000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.113000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -4877,8 +4877,8 @@ SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.717000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.717000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.181000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.181000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -4888,7 +4888,7 @@ SET TRANSACTION READ ONLY; SELECT 1 AS TEST; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.717000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.181000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -5288,15 +5288,15 @@ NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; SET TRANSACTION READ ONLY; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.806000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.806000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.260000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.260000000Z' 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 2024-10-11T16:42:28.806000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.260000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -5641,15 +5641,15 @@ NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; SET READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.877000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.877000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.330000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.330000000Z' 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 2024-10-11T16:42:28.877000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.330000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -6088,8 +6088,8 @@ BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; ROLLBACK; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.956000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.956000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.402000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.402000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -6099,7 +6099,7 @@ BEGIN TRANSACTION; SELECT 1 AS TEST; ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.956000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.402000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -6607,8 +6607,8 @@ BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.068000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.068000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.495000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.495000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -6618,7 +6618,7 @@ BEGIN TRANSACTION; SELECT 1 AS TEST; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.068000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.495000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -7023,15 +7023,15 @@ NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.160000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.160000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.578000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.578000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.160000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.578000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -7394,14 +7394,14 @@ SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.241000000Z'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.654000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.241000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.654000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -7756,13 +7756,13 @@ SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.324000000Z'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.734000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.324000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.734000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -8075,14 +8075,14 @@ SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.398000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.398000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.805000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.805000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.398000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.805000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -8392,13 +8392,13 @@ SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.466000000Z'; +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.865000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.466000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.865000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -8753,8 +8753,8 @@ SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; SET TRANSACTION READ ONLY; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.529000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.529000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.924000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.924000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -8762,7 +8762,7 @@ SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.529000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.924000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -9064,6 +9064,9 @@ 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; +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -9197,8 +9200,8 @@ SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; UPDATE foo SET bar=1; COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.604000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.604000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.991000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.991000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -9206,8 +9209,8 @@ SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; UPDATE foo SET bar=1; COMMIT; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.604000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:29.604000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.991000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:11.991000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -9593,15 +9596,15 @@ NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.688000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.688000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.064000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.064000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.688000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.064000000Z'; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -9851,6 +9854,9 @@ 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; +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -9952,15 +9958,15 @@ NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.757000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.757000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.125000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.125000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.757000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:29.757000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.125000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.125000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -10219,6 +10225,9 @@ 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; +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -10320,15 +10329,15 @@ NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; UPDATE foo SET bar=1; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.831000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.831000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.193000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.193000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; UPDATE foo SET bar=1; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.831000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:29.831000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.193000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.193000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -10601,6 +10610,9 @@ 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; +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -10718,16 +10730,16 @@ SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.905000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.905000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.262000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.262000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.905000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:29.905000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.262000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.262000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -11009,6 +11021,9 @@ 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; +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -11110,15 +11125,15 @@ NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.979000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.979000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.330000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.330000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.979000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:29.979000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.330000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.330000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -11363,6 +11378,9 @@ 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; +SET AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -11448,14 +11466,14 @@ SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.047000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.047000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.396000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.396000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.047000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.047000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.396000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.396000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=FALSE; @@ -11778,15 +11796,15 @@ NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; SET READ_ONLY_STALENESS='MAX_STALENESS 10s'; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.108000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.108000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.456000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.456000000Z' 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 2024-10-11T16:42:30.108000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.108000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.456000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.456000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; @@ -12193,8 +12211,8 @@ SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; SELECT 1 AS TEST; COMMIT; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.171000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.171000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.519000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.519000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; @@ -12202,8 +12220,8 @@ SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; SELECT 1 AS TEST; COMMIT; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.171000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.171000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.519000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.519000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; @@ -12586,15 +12604,15 @@ NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.242000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.242000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.586000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.586000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.242000000Z'; +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.586000000Z'; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; @@ -12932,15 +12950,15 @@ NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.304000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.304000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.650000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.650000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.304000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.304000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.650000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.650000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; @@ -13287,15 +13305,15 @@ NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.372000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.372000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.715000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.715000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.372000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.372000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.715000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.715000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; @@ -13612,14 +13630,14 @@ SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.435000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.435000000Z' +SET READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.778000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.778000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; SET AUTOCOMMIT=TRUE; -SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.435000000Z'; -@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.435000000Z' +SET READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.778000000Z'; +@EXPECT RESULT_SET 'READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.778000000Z' SHOW VARIABLE READ_ONLY_STALENESS; NEW_CONNECTION; SET READONLY=TRUE; diff --git a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/postgresql/ClientSideStatementsTest.sql b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/postgresql/ClientSideStatementsTest.sql index 068210495fa..aea0bf4b808 100644 --- a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/postgresql/ClientSideStatementsTest.sql +++ b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/postgresql/ClientSideStatementsTest.sql @@ -50288,6 +50288,204 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT set/-spanner.autocommit_dml_mode='TRANSACTIONAL'; NEW_CONNECTION; +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +SET SPANNER.AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set spanner.autocommit_dml_mode='transactional_with_fallback_to_partitioned_non_atomic'; +NEW_CONNECTION; + set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; + set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; + + + +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' ; +NEW_CONNECTION; +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' ; +NEW_CONNECTION; +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' + +; +NEW_CONNECTION; +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set +spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +foo set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' bar; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +%set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'%; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set%spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +_set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'_; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set_spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +&set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'&; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set&spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +$set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'$; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set$spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +@set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'@; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set@spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +!set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'!; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set!spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +*set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'*; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set*spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +(set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'(; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set(spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +)set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'); +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set)spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +-set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'-; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set-spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT ++set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'+; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set+spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +-#set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'-#; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set-#spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +/set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'/; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set/spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +\set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'\; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set\spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +?set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'?; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set?spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +-/set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'-/; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set-/spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +/#set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'/#; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set/#spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +/-set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'/-; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set/-spanner.autocommit_dml_mode='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; set spanner.autocommit_dml_mode to 'PARTITIONED_NON_ATOMIC'; NEW_CONNECTION; SET SPANNER.AUTOCOMMIT_DML_MODE TO 'PARTITIONED_NON_ATOMIC'; @@ -50688,6 +50886,206 @@ NEW_CONNECTION; @EXPECT EXCEPTION INVALID_ARGUMENT set spanner.autocommit_dml_mode to/-'TRANSACTIONAL'; NEW_CONNECTION; +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +SET SPANNER.AUTOCOMMIT_DML_MODE TO 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set spanner.autocommit_dml_mode to 'transactional_with_fallback_to_partitioned_non_atomic'; +NEW_CONNECTION; + set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; + set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; + + + +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' ; +NEW_CONNECTION; +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' ; +NEW_CONNECTION; +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' + +; +NEW_CONNECTION; +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +set +spanner.autocommit_dml_mode +to +'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +foo set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' bar; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +%set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'%; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to%'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +_set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'_; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to_'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +&set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'&; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to&'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +$set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'$; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to$'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +@set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'@; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to@'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +!set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'!; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to!'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +*set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'*; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to*'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +(set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'(; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to('TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +)set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'); +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to)'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +-set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'-; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to-'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT ++set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'+; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to+'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +-#set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'-#; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to-#'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +/set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'/; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to/'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +\set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'\; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to\'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +?set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'?; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to?'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +-/set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'-/; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to-/'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +/#set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'/#; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to/#'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +/-set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to 'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'/-; +NEW_CONNECTION; +@EXPECT EXCEPTION INVALID_ARGUMENT +set spanner.autocommit_dml_mode to/-'TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +NEW_CONNECTION; set statement_timeout=default; NEW_CONNECTION; SET STATEMENT_TIMEOUT=DEFAULT; diff --git a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/postgresql/ConnectionImplGeneratedSqlScriptTest.sql b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/postgresql/ConnectionImplGeneratedSqlScriptTest.sql index 75a6a00549c..3db3bda388b 100644 --- a/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/postgresql/ConnectionImplGeneratedSqlScriptTest.sql +++ b/google-cloud-spanner/src/test/resources/com/google/cloud/spanner/connection/postgresql/ConnectionImplGeneratedSqlScriptTest.sql @@ -160,15 +160,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; COMMIT; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:27.628000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:27.628000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.130000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.130000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:27.628000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.130000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -510,15 +510,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; SET SPANNER.READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:27.747000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:27.747000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.240000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.240000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; SET SPANNER.READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:27.747000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.240000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -950,8 +950,8 @@ BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; ROLLBACK; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:27.869000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:27.869000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.352000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.352000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; @@ -961,7 +961,7 @@ BEGIN TRANSACTION; SELECT 1 AS TEST; ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:27.869000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.352000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -1462,8 +1462,8 @@ BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:27.973000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:27.973000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.472000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.472000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; @@ -1473,7 +1473,7 @@ BEGIN TRANSACTION; SELECT 1 AS TEST; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:27.973000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.472000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -1876,15 +1876,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.061000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.061000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.566000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.566000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.061000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.566000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -2243,14 +2243,14 @@ SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.152000000Z'; +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.661000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.152000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.661000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -2600,13 +2600,13 @@ SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.247000000Z'; +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.751000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.247000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.751000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -2910,14 +2910,14 @@ SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.320000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.320000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.827000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.827000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.320000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.827000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=FALSE; @@ -3245,15 +3245,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; COMMIT; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.423000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.423000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:10.925000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:10.925000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.423000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:10.925000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -3662,8 +3662,8 @@ SET AUTOCOMMIT=FALSE; START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); RUN BATCH; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.515000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.515000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.005000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.005000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -3672,7 +3672,7 @@ START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); RUN BATCH; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.515000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.005000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -4081,14 +4081,14 @@ SET AUTOCOMMIT=FALSE; START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.604000000Z'; +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.078000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; START BATCH DDL; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.604000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.078000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -4438,13 +4438,13 @@ SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.673000000Z'; +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.144000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.673000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.144000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -4877,8 +4877,8 @@ SET TRANSACTION READ ONLY; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.765000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.765000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.224000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.224000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -4888,7 +4888,7 @@ SET TRANSACTION READ ONLY; SELECT 1 AS TEST; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.765000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.224000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -5288,15 +5288,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; SET TRANSACTION READ ONLY; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.842000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.842000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.296000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.296000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.842000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.296000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -5641,15 +5641,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; SET SPANNER.READ_ONLY_STALENESS='EXACT_STALENESS 10s'; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:28.915000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:28.915000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.363000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.363000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; SET SPANNER.READ_ONLY_STALENESS='EXACT_STALENESS 10s'; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:28.915000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.363000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -6088,8 +6088,8 @@ BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; ROLLBACK; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.005000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.005000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.444000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.444000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -6099,7 +6099,7 @@ BEGIN TRANSACTION; SELECT 1 AS TEST; ROLLBACK; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.005000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.444000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -6607,8 +6607,8 @@ BEGIN TRANSACTION; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; COMMIT; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.117000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.117000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.539000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.539000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -6618,7 +6618,7 @@ BEGIN TRANSACTION; SELECT 1 AS TEST; COMMIT; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.117000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.539000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -7023,15 +7023,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.203000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.203000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.614000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.614000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.203000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.614000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -7394,14 +7394,14 @@ SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.282000000Z'; +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.693000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.282000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.693000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -7756,13 +7756,13 @@ SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.362000000Z'; +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.771000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; SELECT 1 AS TEST; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.362000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.771000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -8075,14 +8075,14 @@ SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.433000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.433000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.836000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.836000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.433000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.836000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=FALSE; @@ -8392,13 +8392,13 @@ SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.497000000Z'; +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.894000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; START BATCH DDL; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.497000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.894000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -8753,8 +8753,8 @@ SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; SET TRANSACTION READ ONLY; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.562000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.562000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:11.953000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:11.953000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -8762,7 +8762,7 @@ SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; SET TRANSACTION READ ONLY; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.562000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:11.953000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -9064,6 +9064,9 @@ SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; SET SPANNER.AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; @EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; +SET SPANNER.AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -9197,8 +9200,8 @@ SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; UPDATE foo SET bar=1; COMMIT; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.651000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.651000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.028000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.028000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -9206,8 +9209,8 @@ SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; UPDATE foo SET bar=1; COMMIT; -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.651000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:29.651000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.028000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.028000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -9593,15 +9596,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.721000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.721000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.093000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.093000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.721000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.093000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -9851,6 +9854,9 @@ SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; SET SPANNER.AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; @EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; +SET SPANNER.AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -9952,15 +9958,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.792000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.792000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.159000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.159000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; CREATE TABLE foo (id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (id); -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.792000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:29.792000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.159000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.159000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -10219,6 +10225,9 @@ SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; SET SPANNER.AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; @EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; +SET SPANNER.AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -10320,15 +10329,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; UPDATE foo SET bar=1; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.868000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.868000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.227000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.227000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; UPDATE foo SET bar=1; -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.868000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:29.868000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.227000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.227000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -10601,6 +10610,9 @@ SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; SET SPANNER.AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; @EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; +SET SPANNER.AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -10718,16 +10730,16 @@ SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:29.942000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:29.942000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.296000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.296000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @EXPECT RESULT_SET 'TEST',1 SELECT 1 AS TEST; -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:29.942000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:29.942000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.296000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.296000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -11009,6 +11021,9 @@ SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; SET SPANNER.AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; @EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; +SET SPANNER.AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -11110,15 +11125,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.014000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.014000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.365000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.365000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.014000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.014000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.365000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.365000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -11363,6 +11378,9 @@ SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; SET SPANNER.AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'; @EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','PARTITIONED_NON_ATOMIC' SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; +SET SPANNER.AUTOCOMMIT_DML_MODE='TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC'; +@EXPECT RESULT_SET 'SPANNER.AUTOCOMMIT_DML_MODE','TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC' +SHOW VARIABLE SPANNER.AUTOCOMMIT_DML_MODE; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; @@ -11448,14 +11466,14 @@ SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.077000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.077000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.427000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.427000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; SET AUTOCOMMIT=TRUE; -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.077000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.077000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.427000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.427000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=FALSE; @@ -11778,15 +11796,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; SET SPANNER.READ_ONLY_STALENESS='MAX_STALENESS 10s'; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.138000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.138000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.485000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.485000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; SET SPANNER.READ_ONLY_STALENESS='MAX_STALENESS 10s'; -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.138000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.138000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.485000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.485000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; @@ -12193,8 +12211,8 @@ SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; SELECT 1 AS TEST; COMMIT; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.208000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.208000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.555000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.555000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; @@ -12202,8 +12220,8 @@ SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; SELECT 1 AS TEST; COMMIT; -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.208000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.208000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.555000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.555000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; @@ -12586,15 +12604,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.272000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.272000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.615000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.615000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; BEGIN TRANSACTION; @EXPECT EXCEPTION FAILED_PRECONDITION -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.272000000Z'; +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.615000000Z'; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; @@ -12932,15 +12950,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.339000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.339000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.682000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.682000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.339000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.339000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.682000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.682000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; @@ -13287,15 +13305,15 @@ NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.405000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.405000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.747000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.747000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; SELECT 1 AS TEST; -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.405000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.405000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.747000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.747000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; @@ -13612,14 +13630,14 @@ SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; -SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-10-11T16:42:30.465000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-10-11T16:42:30.465000000Z' +SET SPANNER.READ_ONLY_STALENESS='READ_TIMESTAMP 2024-11-25T10:49:12.807000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','READ_TIMESTAMP 2024-11-25T10:49:12.807000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; SET AUTOCOMMIT=TRUE; -SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-10-11T16:42:30.465000000Z'; -@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-10-11T16:42:30.465000000Z' +SET SPANNER.READ_ONLY_STALENESS='MIN_READ_TIMESTAMP 2024-11-25T10:49:12.807000000Z'; +@EXPECT RESULT_SET 'SPANNER.READ_ONLY_STALENESS','MIN_READ_TIMESTAMP 2024-11-25T10:49:12.807000000Z' SHOW VARIABLE SPANNER.READ_ONLY_STALENESS; NEW_CONNECTION; SET SPANNER.READONLY=TRUE; diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index 547eacd5466..000a88b6261 100644 --- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.81.2 + 6.82.0 grpc-google-cloud-spanner-admin-database-v1 GRPC library for grpc-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index c7b56a096b2..b794aca19dd 100644 --- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.81.2 + 6.82.0 grpc-google-cloud-spanner-admin-instance-v1 GRPC library for grpc-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 diff --git a/grpc-google-cloud-spanner-executor-v1/pom.xml b/grpc-google-cloud-spanner-executor-v1/pom.xml index 673bdb94e30..b63e9bd6038 100644 --- a/grpc-google-cloud-spanner-executor-v1/pom.xml +++ b/grpc-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.81.2 + 6.82.0 grpc-google-cloud-spanner-executor-v1 GRPC library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index e78381e76dd..dc1c2c1c936 100644 --- a/grpc-google-cloud-spanner-v1/pom.xml +++ b/grpc-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.81.2 + 6.82.0 grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 diff --git a/pom.xml b/pom.xml index 191e70768a6..72a2a6797e3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.81.2 + 6.82.0 Google Cloud Spanner Parent https://github.com/googleapis/java-spanner @@ -61,47 +61,47 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.81.2 + 6.82.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.81.2 + 6.82.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.81.2 + 6.82.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.81.2 + 6.82.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.81.2 + 6.82.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.81.2 + 6.82.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.81.2 + 6.82.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.81.2 + 6.82.0 com.google.cloud google-cloud-spanner - 6.81.2 + 6.82.0 diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index 8213510c17f..4d29a245a80 100644 --- a/proto-google-cloud-spanner-admin-database-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.81.2 + 6.82.0 proto-google-cloud-spanner-admin-database-v1 PROTO library for proto-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index ce9de4c26db..08da9e3b853 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.81.2 + 6.82.0 proto-google-cloud-spanner-admin-instance-v1 PROTO library for proto-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 diff --git a/proto-google-cloud-spanner-executor-v1/pom.xml b/proto-google-cloud-spanner-executor-v1/pom.xml index 2f673705bb9..23a213ca72f 100644 --- a/proto-google-cloud-spanner-executor-v1/pom.xml +++ b/proto-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.81.2 + 6.82.0 proto-google-cloud-spanner-executor-v1 Proto library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index bfc8d4b53b8..8c3dc7a8adf 100644 --- a/proto-google-cloud-spanner-v1/pom.xml +++ b/proto-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.81.2 + 6.82.0 proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.81.2 + 6.82.0 diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequest.java index e829327651b..55cce1f9922 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequest.java @@ -2100,6 +2100,32 @@ public com.google.spanner.v1.RequestOptionsOrBuilder getRequestOptionsOrBuilder( : requestOptions_; } + public static final int LAST_STATEMENTS_FIELD_NUMBER = 6; + private boolean lastStatements_ = false; + /** + * + * + *
+   * Optional. If set to true, this request marks the end of the transaction.
+   * The transaction should be committed or aborted after these statements
+   * execute, and attempts to execute any other requests against this
+   * transaction (including reads and queries) will be rejected.
+   *
+   * Setting this option may cause some error reporting to be deferred until
+   * commit time (e.g. validation of unique constraints). Given this, successful
+   * execution of statements should not be assumed until a subsequent Commit
+   * call completes successfully.
+   * 
+ * + * bool last_statements = 6 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The lastStatements. + */ + @java.lang.Override + public boolean getLastStatements() { + return lastStatements_; + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -2129,6 +2155,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io if (((bitField0_ & 0x00000002) != 0)) { output.writeMessage(5, getRequestOptions()); } + if (lastStatements_ != false) { + output.writeBool(6, lastStatements_); + } getUnknownFields().writeTo(output); } @@ -2153,6 +2182,9 @@ public int getSerializedSize() { if (((bitField0_ & 0x00000002) != 0)) { size += com.google.protobuf.CodedOutputStream.computeMessageSize(5, getRequestOptions()); } + if (lastStatements_ != false) { + size += com.google.protobuf.CodedOutputStream.computeBoolSize(6, lastStatements_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -2180,6 +2212,7 @@ public boolean equals(final java.lang.Object obj) { if (hasRequestOptions()) { if (!getRequestOptions().equals(other.getRequestOptions())) return false; } + if (getLastStatements() != other.getLastStatements()) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -2207,6 +2240,8 @@ public int hashCode() { hash = (37 * hash) + REQUEST_OPTIONS_FIELD_NUMBER; hash = (53 * hash) + getRequestOptions().hashCode(); } + hash = (37 * hash) + LAST_STATEMENTS_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(getLastStatements()); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -2376,6 +2411,7 @@ public Builder clear() { requestOptionsBuilder_.dispose(); requestOptionsBuilder_ = null; } + lastStatements_ = false; return this; } @@ -2442,6 +2478,9 @@ private void buildPartial0(com.google.spanner.v1.ExecuteBatchDmlRequest result) requestOptionsBuilder_ == null ? requestOptions_ : requestOptionsBuilder_.build(); to_bitField0_ |= 0x00000002; } + if (((from_bitField0_ & 0x00000020) != 0)) { + result.lastStatements_ = lastStatements_; + } result.bitField0_ |= to_bitField0_; } @@ -2531,6 +2570,9 @@ public Builder mergeFrom(com.google.spanner.v1.ExecuteBatchDmlRequest other) { if (other.hasRequestOptions()) { mergeRequestOptions(other.getRequestOptions()); } + if (other.getLastStatements() != false) { + setLastStatements(other.getLastStatements()); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -2595,6 +2637,12 @@ public Builder mergeFrom( bitField0_ |= 0x00000010; break; } // case 42 + case 48: + { + lastStatements_ = input.readBool(); + bitField0_ |= 0x00000020; + break; + } // case 48 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -3715,6 +3763,83 @@ public com.google.spanner.v1.RequestOptionsOrBuilder getRequestOptionsOrBuilder( return requestOptionsBuilder_; } + private boolean lastStatements_; + /** + * + * + *
+     * Optional. If set to true, this request marks the end of the transaction.
+     * The transaction should be committed or aborted after these statements
+     * execute, and attempts to execute any other requests against this
+     * transaction (including reads and queries) will be rejected.
+     *
+     * Setting this option may cause some error reporting to be deferred until
+     * commit time (e.g. validation of unique constraints). Given this, successful
+     * execution of statements should not be assumed until a subsequent Commit
+     * call completes successfully.
+     * 
+ * + * bool last_statements = 6 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The lastStatements. + */ + @java.lang.Override + public boolean getLastStatements() { + return lastStatements_; + } + /** + * + * + *
+     * Optional. If set to true, this request marks the end of the transaction.
+     * The transaction should be committed or aborted after these statements
+     * execute, and attempts to execute any other requests against this
+     * transaction (including reads and queries) will be rejected.
+     *
+     * Setting this option may cause some error reporting to be deferred until
+     * commit time (e.g. validation of unique constraints). Given this, successful
+     * execution of statements should not be assumed until a subsequent Commit
+     * call completes successfully.
+     * 
+ * + * bool last_statements = 6 [(.google.api.field_behavior) = OPTIONAL]; + * + * @param value The lastStatements to set. + * @return This builder for chaining. + */ + public Builder setLastStatements(boolean value) { + + lastStatements_ = value; + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + * + * + *
+     * Optional. If set to true, this request marks the end of the transaction.
+     * The transaction should be committed or aborted after these statements
+     * execute, and attempts to execute any other requests against this
+     * transaction (including reads and queries) will be rejected.
+     *
+     * Setting this option may cause some error reporting to be deferred until
+     * commit time (e.g. validation of unique constraints). Given this, successful
+     * execution of statements should not be assumed until a subsequent Commit
+     * call completes successfully.
+     * 
+ * + * bool last_statements = 6 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return This builder for chaining. + */ + public Builder clearLastStatements() { + bitField0_ = (bitField0_ & ~0x00000020); + lastStatements_ = false; + onChanged(); + return this; + } + @java.lang.Override public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequestOrBuilder.java index cdada2baa3f..db35333cf19 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteBatchDmlRequestOrBuilder.java @@ -247,4 +247,25 @@ public interface ExecuteBatchDmlRequestOrBuilder * .google.spanner.v1.RequestOptions request_options = 5; */ com.google.spanner.v1.RequestOptionsOrBuilder getRequestOptionsOrBuilder(); + + /** + * + * + *
+   * Optional. If set to true, this request marks the end of the transaction.
+   * The transaction should be committed or aborted after these statements
+   * execute, and attempts to execute any other requests against this
+   * transaction (including reads and queries) will be rejected.
+   *
+   * Setting this option may cause some error reporting to be deferred until
+   * commit time (e.g. validation of unique constraints). Given this, successful
+   * execution of statements should not be assumed until a subsequent Commit
+   * call completes successfully.
+   * 
+ * + * bool last_statements = 6 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The lastStatements. + */ + boolean getLastStatements(); } diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequest.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequest.java index 94ec19c8db9..1f31567db20 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequest.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequest.java @@ -2234,6 +2234,32 @@ public boolean getDataBoostEnabled() { return dataBoostEnabled_; } + public static final int LAST_STATEMENT_FIELD_NUMBER = 17; + private boolean lastStatement_ = false; + /** + * + * + *
+   * Optional. If set to true, this statement marks the end of the transaction.
+   * The transaction should be committed or aborted after this statement
+   * executes, and attempts to execute any other requests against this
+   * transaction (including reads and queries) will be rejected.
+   *
+   * For DML statements, setting this option may cause some error reporting to
+   * be deferred until commit time (e.g. validation of unique constraints).
+   * Given this, successful execution of a DML statement should not be assumed
+   * until a subsequent Commit call completes successfully.
+   * 
+ * + * bool last_statement = 17 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The lastStatement. + */ + @java.lang.Override + public boolean getLastStatement() { + return lastStatement_; + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -2286,6 +2312,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io if (dataBoostEnabled_ != false) { output.writeBool(16, dataBoostEnabled_); } + if (lastStatement_ != false) { + output.writeBool(17, lastStatement_); + } getUnknownFields().writeTo(output); } @@ -2342,6 +2371,9 @@ public int getSerializedSize() { if (dataBoostEnabled_ != false) { size += com.google.protobuf.CodedOutputStream.computeBoolSize(16, dataBoostEnabled_); } + if (lastStatement_ != false) { + size += com.google.protobuf.CodedOutputStream.computeBoolSize(17, lastStatement_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -2385,6 +2417,7 @@ public boolean equals(final java.lang.Object obj) { if (!getDirectedReadOptions().equals(other.getDirectedReadOptions())) return false; } if (getDataBoostEnabled() != other.getDataBoostEnabled()) return false; + if (getLastStatement() != other.getLastStatement()) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -2434,6 +2467,8 @@ public int hashCode() { } hash = (37 * hash) + DATA_BOOST_ENABLED_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(getDataBoostEnabled()); + hash = (37 * hash) + LAST_STATEMENT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(getLastStatement()); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -2642,6 +2677,7 @@ public Builder clear() { directedReadOptionsBuilder_ = null; } dataBoostEnabled_ = false; + lastStatement_ = false; return this; } @@ -2730,6 +2766,9 @@ private void buildPartial0(com.google.spanner.v1.ExecuteSqlRequest result) { if (((from_bitField0_ & 0x00001000) != 0)) { result.dataBoostEnabled_ = dataBoostEnabled_; } + if (((from_bitField0_ & 0x00002000) != 0)) { + result.lastStatement_ = lastStatement_; + } result.bitField0_ |= to_bitField0_; } @@ -2820,6 +2859,9 @@ public Builder mergeFrom(com.google.spanner.v1.ExecuteSqlRequest other) { if (other.getDataBoostEnabled() != false) { setDataBoostEnabled(other.getDataBoostEnabled()); } + if (other.getLastStatement() != false) { + setLastStatement(other.getLastStatement()); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -2932,6 +2974,12 @@ public Builder mergeFrom( bitField0_ |= 0x00001000; break; } // case 128 + case 136: + { + lastStatement_ = input.readBool(); + bitField0_ |= 0x00002000; + break; + } // case 136 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -4975,6 +5023,83 @@ public Builder clearDataBoostEnabled() { return this; } + private boolean lastStatement_; + /** + * + * + *
+     * Optional. If set to true, this statement marks the end of the transaction.
+     * The transaction should be committed or aborted after this statement
+     * executes, and attempts to execute any other requests against this
+     * transaction (including reads and queries) will be rejected.
+     *
+     * For DML statements, setting this option may cause some error reporting to
+     * be deferred until commit time (e.g. validation of unique constraints).
+     * Given this, successful execution of a DML statement should not be assumed
+     * until a subsequent Commit call completes successfully.
+     * 
+ * + * bool last_statement = 17 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The lastStatement. + */ + @java.lang.Override + public boolean getLastStatement() { + return lastStatement_; + } + /** + * + * + *
+     * Optional. If set to true, this statement marks the end of the transaction.
+     * The transaction should be committed or aborted after this statement
+     * executes, and attempts to execute any other requests against this
+     * transaction (including reads and queries) will be rejected.
+     *
+     * For DML statements, setting this option may cause some error reporting to
+     * be deferred until commit time (e.g. validation of unique constraints).
+     * Given this, successful execution of a DML statement should not be assumed
+     * until a subsequent Commit call completes successfully.
+     * 
+ * + * bool last_statement = 17 [(.google.api.field_behavior) = OPTIONAL]; + * + * @param value The lastStatement to set. + * @return This builder for chaining. + */ + public Builder setLastStatement(boolean value) { + + lastStatement_ = value; + bitField0_ |= 0x00002000; + onChanged(); + return this; + } + /** + * + * + *
+     * Optional. If set to true, this statement marks the end of the transaction.
+     * The transaction should be committed or aborted after this statement
+     * executes, and attempts to execute any other requests against this
+     * transaction (including reads and queries) will be rejected.
+     *
+     * For DML statements, setting this option may cause some error reporting to
+     * be deferred until commit time (e.g. validation of unique constraints).
+     * Given this, successful execution of a DML statement should not be assumed
+     * until a subsequent Commit call completes successfully.
+     * 
+ * + * bool last_statement = 17 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return This builder for chaining. + */ + public Builder clearLastStatement() { + bitField0_ = (bitField0_ & ~0x00002000); + lastStatement_ = false; + onChanged(); + return this; + } + @java.lang.Override public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequestOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequestOrBuilder.java index de635dc34e2..a9fa97f75de 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequestOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ExecuteSqlRequestOrBuilder.java @@ -521,4 +521,25 @@ com.google.spanner.v1.Type getParamTypesOrDefault( * @return The dataBoostEnabled. */ boolean getDataBoostEnabled(); + + /** + * + * + *
+   * Optional. If set to true, this statement marks the end of the transaction.
+   * The transaction should be committed or aborted after this statement
+   * executes, and attempts to execute any other requests against this
+   * transaction (including reads and queries) will be rejected.
+   *
+   * For DML statements, setting this option may cause some error reporting to
+   * be deferred until commit time (e.g. validation of unique constraints).
+   * Given this, successful execution of a DML statement should not be assumed
+   * until a subsequent Commit call completes successfully.
+   * 
+ * + * bool last_statement = 17 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The lastStatement. + */ + boolean getLastStatement(); } diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java index d8679c5b35d..0be619a96af 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/SpannerProto.java @@ -236,8 +236,8 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "aSelection\022\036\n\026auto_failover_disabled\030\002 \001" + "(\010\032f\n\017ExcludeReplicas\022S\n\022replica_selecti" + "ons\030\001 \003(\01327.google.spanner.v1.DirectedRe" - + "adOptions.ReplicaSelectionB\n\n\010replicas\"\360" - + "\006\n\021ExecuteSqlRequest\0227\n\007session\030\001 \001(\tB&\340" + + "adOptions.ReplicaSelectionB\n\n\010replicas\"\215" + + "\007\n\021ExecuteSqlRequest\0227\n\007session\030\001 \001(\tB&\340" + "A\002\372A \n\036spanner.googleapis.com/Session\022;\n" + "\013transaction\030\002 \001(\0132&.google.spanner.v1.T" + "ransactionSelector\022\020\n\003sql\030\003 \001(\tB\003\340A\002\022\'\n\006" @@ -252,192 +252,194 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "request_options\030\013 \001(\0132!.google.spanner.v" + "1.RequestOptions\022E\n\025directed_read_option" + "s\030\017 \001(\0132&.google.spanner.v1.DirectedRead" - + "Options\022\032\n\022data_boost_enabled\030\020 \001(\010\032O\n\014Q" - + "ueryOptions\022\031\n\021optimizer_version\030\001 \001(\t\022$" - + "\n\034optimizer_statistics_package\030\002 \001(\t\032J\n\017" - + "ParamTypesEntry\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 " - + "\001(\0132\027.google.spanner.v1.Type:\0028\001\"W\n\tQuer" - + "yMode\022\n\n\006NORMAL\020\000\022\010\n\004PLAN\020\001\022\013\n\007PROFILE\020\002" - + "\022\016\n\nWITH_STATS\020\003\022\027\n\023WITH_PLAN_AND_STATS\020" - + "\004\"\240\004\n\026ExecuteBatchDmlRequest\0227\n\007session\030" - + "\001 \001(\tB&\340A\002\372A \n\036spanner.googleapis.com/Se" - + "ssion\022@\n\013transaction\030\002 \001(\0132&.google.span" - + "ner.v1.TransactionSelectorB\003\340A\002\022L\n\nstate" - + "ments\030\003 \003(\01323.google.spanner.v1.ExecuteB" - + "atchDmlRequest.StatementB\003\340A\002\022\022\n\005seqno\030\004" - + " \001(\003B\003\340A\002\022:\n\017request_options\030\005 \001(\0132!.goo" - + "gle.spanner.v1.RequestOptions\032\354\001\n\tStatem" - + "ent\022\020\n\003sql\030\001 \001(\tB\003\340A\002\022\'\n\006params\030\002 \001(\0132\027." - + "google.protobuf.Struct\022X\n\013param_types\030\003 " - + "\003(\0132C.google.spanner.v1.ExecuteBatchDmlR" - + "equest.Statement.ParamTypesEntry\032J\n\017Para" - + "mTypesEntry\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 \001(\0132" - + "\027.google.spanner.v1.Type:\0028\001\"\303\001\n\027Execute" - + "BatchDmlResponse\0221\n\013result_sets\030\001 \003(\0132\034." - + "google.spanner.v1.ResultSet\022\"\n\006status\030\002 " - + "\001(\0132\022.google.rpc.Status\022Q\n\017precommit_tok" - + "en\030\003 \001(\01323.google.spanner.v1.Multiplexed" - + "SessionPrecommitTokenB\003\340A\001\"H\n\020PartitionO" - + "ptions\022\034\n\024partition_size_bytes\030\001 \001(\003\022\026\n\016" - + "max_partitions\030\002 \001(\003\"\243\003\n\025PartitionQueryR" + + "Options\022\032\n\022data_boost_enabled\030\020 \001(\010\022\033\n\016l" + + "ast_statement\030\021 \001(\010B\003\340A\001\032O\n\014QueryOptions" + + "\022\031\n\021optimizer_version\030\001 \001(\t\022$\n\034optimizer" + + "_statistics_package\030\002 \001(\t\032J\n\017ParamTypesE" + + "ntry\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 \001(\0132\027.googl" + + "e.spanner.v1.Type:\0028\001\"W\n\tQueryMode\022\n\n\006NO" + + "RMAL\020\000\022\010\n\004PLAN\020\001\022\013\n\007PROFILE\020\002\022\016\n\nWITH_ST" + + "ATS\020\003\022\027\n\023WITH_PLAN_AND_STATS\020\004\"\276\004\n\026Execu" + + "teBatchDmlRequest\0227\n\007session\030\001 \001(\tB&\340A\002\372" + + "A \n\036spanner.googleapis.com/Session\022@\n\013tr" + + "ansaction\030\002 \001(\0132&.google.spanner.v1.Tran" + + "sactionSelectorB\003\340A\002\022L\n\nstatements\030\003 \003(\013" + + "23.google.spanner.v1.ExecuteBatchDmlRequ" + + "est.StatementB\003\340A\002\022\022\n\005seqno\030\004 \001(\003B\003\340A\002\022:" + + "\n\017request_options\030\005 \001(\0132!.google.spanner" + + ".v1.RequestOptions\022\034\n\017last_statements\030\006 " + + "\001(\010B\003\340A\001\032\354\001\n\tStatement\022\020\n\003sql\030\001 \001(\tB\003\340A\002" + + "\022\'\n\006params\030\002 \001(\0132\027.google.protobuf.Struc" + + "t\022X\n\013param_types\030\003 \003(\0132C.google.spanner." + + "v1.ExecuteBatchDmlRequest.Statement.Para" + + "mTypesEntry\032J\n\017ParamTypesEntry\022\013\n\003key\030\001 " + + "\001(\t\022&\n\005value\030\002 \001(\0132\027.google.spanner.v1.T" + + "ype:\0028\001\"\303\001\n\027ExecuteBatchDmlResponse\0221\n\013r" + + "esult_sets\030\001 \003(\0132\034.google.spanner.v1.Res" + + "ultSet\022\"\n\006status\030\002 \001(\0132\022.google.rpc.Stat" + + "us\022Q\n\017precommit_token\030\003 \001(\01323.google.spa" + + "nner.v1.MultiplexedSessionPrecommitToken" + + "B\003\340A\001\"H\n\020PartitionOptions\022\034\n\024partition_s" + + "ize_bytes\030\001 \001(\003\022\026\n\016max_partitions\030\002 \001(\003\"" + + "\243\003\n\025PartitionQueryRequest\0227\n\007session\030\001 \001" + + "(\tB&\340A\002\372A \n\036spanner.googleapis.com/Sessi" + + "on\022;\n\013transaction\030\002 \001(\0132&.google.spanner" + + ".v1.TransactionSelector\022\020\n\003sql\030\003 \001(\tB\003\340A" + + "\002\022\'\n\006params\030\004 \001(\0132\027.google.protobuf.Stru" + + "ct\022M\n\013param_types\030\005 \003(\01328.google.spanner" + + ".v1.PartitionQueryRequest.ParamTypesEntr" + + "y\022>\n\021partition_options\030\006 \001(\0132#.google.sp" + + "anner.v1.PartitionOptions\032J\n\017ParamTypesE" + + "ntry\022\013\n\003key\030\001 \001(\t\022&\n\005value\030\002 \001(\0132\027.googl" + + "e.spanner.v1.Type:\0028\001\"\261\002\n\024PartitionReadR" + "equest\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036spanner" + ".googleapis.com/Session\022;\n\013transaction\030\002" + " \001(\0132&.google.spanner.v1.TransactionSele" - + "ctor\022\020\n\003sql\030\003 \001(\tB\003\340A\002\022\'\n\006params\030\004 \001(\0132\027" - + ".google.protobuf.Struct\022M\n\013param_types\030\005" - + " \003(\01328.google.spanner.v1.PartitionQueryR" - + "equest.ParamTypesEntry\022>\n\021partition_opti" - + "ons\030\006 \001(\0132#.google.spanner.v1.PartitionO" - + "ptions\032J\n\017ParamTypesEntry\022\013\n\003key\030\001 \001(\t\022&" - + "\n\005value\030\002 \001(\0132\027.google.spanner.v1.Type:\002" - + "8\001\"\261\002\n\024PartitionReadRequest\0227\n\007session\030\001" + + "ctor\022\022\n\005table\030\003 \001(\tB\003\340A\002\022\r\n\005index\030\004 \001(\t\022" + + "\017\n\007columns\030\005 \003(\t\022/\n\007key_set\030\006 \001(\0132\031.goog" + + "le.spanner.v1.KeySetB\003\340A\002\022>\n\021partition_o" + + "ptions\030\t \001(\0132#.google.spanner.v1.Partiti" + + "onOptions\"$\n\tPartition\022\027\n\017partition_toke" + + "n\030\001 \001(\014\"z\n\021PartitionResponse\0220\n\npartitio" + + "ns\030\001 \003(\0132\034.google.spanner.v1.Partition\0223" + + "\n\013transaction\030\002 \001(\0132\036.google.spanner.v1." + + "Transaction\"\366\005\n\013ReadRequest\0227\n\007session\030\001" + " \001(\tB&\340A\002\372A \n\036spanner.googleapis.com/Ses" + "sion\022;\n\013transaction\030\002 \001(\0132&.google.spann" + "er.v1.TransactionSelector\022\022\n\005table\030\003 \001(\t" - + "B\003\340A\002\022\r\n\005index\030\004 \001(\t\022\017\n\007columns\030\005 \003(\t\022/\n" - + "\007key_set\030\006 \001(\0132\031.google.spanner.v1.KeySe" - + "tB\003\340A\002\022>\n\021partition_options\030\t \001(\0132#.goog" - + "le.spanner.v1.PartitionOptions\"$\n\tPartit" - + "ion\022\027\n\017partition_token\030\001 \001(\014\"z\n\021Partitio" - + "nResponse\0220\n\npartitions\030\001 \003(\0132\034.google.s" - + "panner.v1.Partition\0223\n\013transaction\030\002 \001(\013" - + "2\036.google.spanner.v1.Transaction\"\366\005\n\013Rea" - + "dRequest\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036spann" - + "er.googleapis.com/Session\022;\n\013transaction" - + "\030\002 \001(\0132&.google.spanner.v1.TransactionSe" - + "lector\022\022\n\005table\030\003 \001(\tB\003\340A\002\022\r\n\005index\030\004 \001(" - + "\t\022\024\n\007columns\030\005 \003(\tB\003\340A\002\022/\n\007key_set\030\006 \001(\013" - + "2\031.google.spanner.v1.KeySetB\003\340A\002\022\r\n\005limi" - + "t\030\010 \001(\003\022\024\n\014resume_token\030\t \001(\014\022\027\n\017partiti" - + "on_token\030\n \001(\014\022:\n\017request_options\030\013 \001(\0132" - + "!.google.spanner.v1.RequestOptions\022E\n\025di" - + "rected_read_options\030\016 \001(\0132&.google.spann" - + "er.v1.DirectedReadOptions\022\032\n\022data_boost_" - + "enabled\030\017 \001(\010\022=\n\010order_by\030\020 \001(\0162&.google" - + ".spanner.v1.ReadRequest.OrderByB\003\340A\001\022?\n\t" - + "lock_hint\030\021 \001(\0162\'.google.spanner.v1.Read" - + "Request.LockHintB\003\340A\001\"T\n\007OrderBy\022\030\n\024ORDE" - + "R_BY_UNSPECIFIED\020\000\022\030\n\024ORDER_BY_PRIMARY_K" - + "EY\020\001\022\025\n\021ORDER_BY_NO_ORDER\020\002\"T\n\010LockHint\022" - + "\031\n\025LOCK_HINT_UNSPECIFIED\020\000\022\024\n\020LOCK_HINT_" - + "SHARED\020\001\022\027\n\023LOCK_HINT_EXCLUSIVE\020\002\"\203\002\n\027Be" - + "ginTransactionRequest\0227\n\007session\030\001 \001(\tB&" - + "\340A\002\372A \n\036spanner.googleapis.com/Session\022;" - + "\n\007options\030\002 \001(\0132%.google.spanner.v1.Tran" - + "sactionOptionsB\003\340A\002\022:\n\017request_options\030\003" - + " \001(\0132!.google.spanner.v1.RequestOptions\022" - + "6\n\014mutation_key\030\004 \001(\0132\033.google.spanner.v" - + "1.MutationB\003\340A\001\"\320\003\n\rCommitRequest\0227\n\007ses" - + "sion\030\001 \001(\tB&\340A\002\372A \n\036spanner.googleapis.c" - + "om/Session\022\030\n\016transaction_id\030\002 \001(\014H\000\022G\n\026" - + "single_use_transaction\030\003 \001(\0132%.google.sp" - + "anner.v1.TransactionOptionsH\000\022.\n\tmutatio" - + "ns\030\004 \003(\0132\033.google.spanner.v1.Mutation\022\033\n" - + "\023return_commit_stats\030\005 \001(\010\0228\n\020max_commit" - + "_delay\030\010 \001(\0132\031.google.protobuf.DurationB" - + "\003\340A\001\022:\n\017request_options\030\006 \001(\0132!.google.s" - + "panner.v1.RequestOptions\022Q\n\017precommit_to" - + "ken\030\t \001(\01323.google.spanner.v1.Multiplexe" - + "dSessionPrecommitTokenB\003\340A\001B\r\n\013transacti" - + "on\"g\n\017RollbackRequest\0227\n\007session\030\001 \001(\tB&" - + "\340A\002\372A \n\036spanner.googleapis.com/Session\022\033" - + "\n\016transaction_id\030\002 \001(\014B\003\340A\002\"\316\002\n\021BatchWri" - + "teRequest\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036span" - + "ner.googleapis.com/Session\022:\n\017request_op" - + "tions\030\003 \001(\0132!.google.spanner.v1.RequestO" - + "ptions\022P\n\017mutation_groups\030\004 \003(\01322.google" - + ".spanner.v1.BatchWriteRequest.MutationGr" - + "oupB\003\340A\002\022,\n\037exclude_txn_from_change_stre" - + "ams\030\005 \001(\010B\003\340A\001\032D\n\rMutationGroup\0223\n\tmutat" - + "ions\030\001 \003(\0132\033.google.spanner.v1.MutationB" - + "\003\340A\002\"\177\n\022BatchWriteResponse\022\017\n\007indexes\030\001 " - + "\003(\005\022\"\n\006status\030\002 \001(\0132\022.google.rpc.Status\022" - + "4\n\020commit_timestamp\030\003 \001(\0132\032.google.proto" - + "buf.Timestamp2\213\030\n\007Spanner\022\246\001\n\rCreateSess" - + "ion\022\'.google.spanner.v1.CreateSessionReq" - + "uest\032\032.google.spanner.v1.Session\"P\332A\010dat" - + "abase\202\323\344\223\002?\":/v1/{database=projects/*/in" - + "stances/*/databases/*}/sessions:\001*\022\340\001\n\023B" - + "atchCreateSessions\022-.google.spanner.v1.B" - + "atchCreateSessionsRequest\032..google.spann" - + "er.v1.BatchCreateSessionsResponse\"j\332A\026da" - + "tabase,session_count\202\323\344\223\002K\"F/v1/{databas" - + "e=projects/*/instances/*/databases/*}/se" - + "ssions:batchCreate:\001*\022\227\001\n\nGetSession\022$.g" - + "oogle.spanner.v1.GetSessionRequest\032\032.goo" - + "gle.spanner.v1.Session\"G\332A\004name\202\323\344\223\002:\0228/" - + "v1/{name=projects/*/instances/*/database" - + "s/*/sessions/*}\022\256\001\n\014ListSessions\022&.googl" - + "e.spanner.v1.ListSessionsRequest\032\'.googl" - + "e.spanner.v1.ListSessionsResponse\"M\332A\010da" - + "tabase\202\323\344\223\002<\022:/v1/{database=projects/*/i" - + "nstances/*/databases/*}/sessions\022\231\001\n\rDel" - + "eteSession\022\'.google.spanner.v1.DeleteSes" - + "sionRequest\032\026.google.protobuf.Empty\"G\332A\004" - + "name\202\323\344\223\002:*8/v1/{name=projects/*/instanc" - + "es/*/databases/*/sessions/*}\022\243\001\n\nExecute" - + "Sql\022$.google.spanner.v1.ExecuteSqlReques" - + "t\032\034.google.spanner.v1.ResultSet\"Q\202\323\344\223\002K\"" - + "F/v1/{session=projects/*/instances/*/dat" - + "abases/*/sessions/*}:executeSql:\001*\022\276\001\n\023E" - + "xecuteStreamingSql\022$.google.spanner.v1.E" - + "xecuteSqlRequest\032#.google.spanner.v1.Par" - + "tialResultSet\"Z\202\323\344\223\002T\"O/v1/{session=proj" - + "ects/*/instances/*/databases/*/sessions/" - + "*}:executeStreamingSql:\001*0\001\022\300\001\n\017ExecuteB" - + "atchDml\022).google.spanner.v1.ExecuteBatch" - + "DmlRequest\032*.google.spanner.v1.ExecuteBa" - + "tchDmlResponse\"V\202\323\344\223\002P\"K/v1/{session=pro" - + "jects/*/instances/*/databases/*/sessions" - + "/*}:executeBatchDml:\001*\022\221\001\n\004Read\022\036.google" - + ".spanner.v1.ReadRequest\032\034.google.spanner" - + ".v1.ResultSet\"K\202\323\344\223\002E\"@/v1/{session=proj" - + "ects/*/instances/*/databases/*/sessions/" - + "*}:read:\001*\022\254\001\n\rStreamingRead\022\036.google.sp" - + "anner.v1.ReadRequest\032#.google.spanner.v1" - + ".PartialResultSet\"T\202\323\344\223\002N\"I/v1/{session=" - + "projects/*/instances/*/databases/*/sessi" - + "ons/*}:streamingRead:\001*0\001\022\311\001\n\020BeginTrans" - + "action\022*.google.spanner.v1.BeginTransact" - + "ionRequest\032\036.google.spanner.v1.Transacti" - + "on\"i\332A\017session,options\202\323\344\223\002Q\"L/v1/{sessi" - + "on=projects/*/instances/*/databases/*/se" - + "ssions/*}:beginTransaction:\001*\022\353\001\n\006Commit" - + "\022 .google.spanner.v1.CommitRequest\032!.goo" - + "gle.spanner.v1.CommitResponse\"\233\001\332A sessi" - + "on,transaction_id,mutations\332A(session,si" - + "ngle_use_transaction,mutations\202\323\344\223\002G\"B/v" + + "B\003\340A\002\022\r\n\005index\030\004 \001(\t\022\024\n\007columns\030\005 \003(\tB\003\340" + + "A\002\022/\n\007key_set\030\006 \001(\0132\031.google.spanner.v1." + + "KeySetB\003\340A\002\022\r\n\005limit\030\010 \001(\003\022\024\n\014resume_tok" + + "en\030\t \001(\014\022\027\n\017partition_token\030\n \001(\014\022:\n\017req" + + "uest_options\030\013 \001(\0132!.google.spanner.v1.R" + + "equestOptions\022E\n\025directed_read_options\030\016" + + " \001(\0132&.google.spanner.v1.DirectedReadOpt" + + "ions\022\032\n\022data_boost_enabled\030\017 \001(\010\022=\n\010orde" + + "r_by\030\020 \001(\0162&.google.spanner.v1.ReadReque" + + "st.OrderByB\003\340A\001\022?\n\tlock_hint\030\021 \001(\0162\'.goo" + + "gle.spanner.v1.ReadRequest.LockHintB\003\340A\001" + + "\"T\n\007OrderBy\022\030\n\024ORDER_BY_UNSPECIFIED\020\000\022\030\n" + + "\024ORDER_BY_PRIMARY_KEY\020\001\022\025\n\021ORDER_BY_NO_O" + + "RDER\020\002\"T\n\010LockHint\022\031\n\025LOCK_HINT_UNSPECIF" + + "IED\020\000\022\024\n\020LOCK_HINT_SHARED\020\001\022\027\n\023LOCK_HINT" + + "_EXCLUSIVE\020\002\"\203\002\n\027BeginTransactionRequest" + + "\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036spanner.googl" + + "eapis.com/Session\022;\n\007options\030\002 \001(\0132%.goo" + + "gle.spanner.v1.TransactionOptionsB\003\340A\002\022:" + + "\n\017request_options\030\003 \001(\0132!.google.spanner" + + ".v1.RequestOptions\0226\n\014mutation_key\030\004 \001(\013" + + "2\033.google.spanner.v1.MutationB\003\340A\001\"\320\003\n\rC" + + "ommitRequest\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036s" + + "panner.googleapis.com/Session\022\030\n\016transac" + + "tion_id\030\002 \001(\014H\000\022G\n\026single_use_transactio" + + "n\030\003 \001(\0132%.google.spanner.v1.TransactionO" + + "ptionsH\000\022.\n\tmutations\030\004 \003(\0132\033.google.spa" + + "nner.v1.Mutation\022\033\n\023return_commit_stats\030" + + "\005 \001(\010\0228\n\020max_commit_delay\030\010 \001(\0132\031.google" + + ".protobuf.DurationB\003\340A\001\022:\n\017request_optio" + + "ns\030\006 \001(\0132!.google.spanner.v1.RequestOpti" + + "ons\022Q\n\017precommit_token\030\t \001(\01323.google.sp" + + "anner.v1.MultiplexedSessionPrecommitToke" + + "nB\003\340A\001B\r\n\013transaction\"g\n\017RollbackRequest" + + "\0227\n\007session\030\001 \001(\tB&\340A\002\372A \n\036spanner.googl" + + "eapis.com/Session\022\033\n\016transaction_id\030\002 \001(" + + "\014B\003\340A\002\"\316\002\n\021BatchWriteRequest\0227\n\007session\030" + + "\001 \001(\tB&\340A\002\372A \n\036spanner.googleapis.com/Se" + + "ssion\022:\n\017request_options\030\003 \001(\0132!.google." + + "spanner.v1.RequestOptions\022P\n\017mutation_gr" + + "oups\030\004 \003(\01322.google.spanner.v1.BatchWrit" + + "eRequest.MutationGroupB\003\340A\002\022,\n\037exclude_t" + + "xn_from_change_streams\030\005 \001(\010B\003\340A\001\032D\n\rMut" + + "ationGroup\0223\n\tmutations\030\001 \003(\0132\033.google.s" + + "panner.v1.MutationB\003\340A\002\"\177\n\022BatchWriteRes" + + "ponse\022\017\n\007indexes\030\001 \003(\005\022\"\n\006status\030\002 \001(\0132\022" + + ".google.rpc.Status\0224\n\020commit_timestamp\030\003" + + " \001(\0132\032.google.protobuf.Timestamp2\213\030\n\007Spa" + + "nner\022\246\001\n\rCreateSession\022\'.google.spanner." + + "v1.CreateSessionRequest\032\032.google.spanner" + + ".v1.Session\"P\332A\010database\202\323\344\223\002?\":/v1/{dat" + + "abase=projects/*/instances/*/databases/*" + + "}/sessions:\001*\022\340\001\n\023BatchCreateSessions\022-." + + "google.spanner.v1.BatchCreateSessionsReq" + + "uest\032..google.spanner.v1.BatchCreateSess" + + "ionsResponse\"j\332A\026database,session_count\202" + + "\323\344\223\002K\"F/v1/{database=projects/*/instance" + + "s/*/databases/*}/sessions:batchCreate:\001*" + + "\022\227\001\n\nGetSession\022$.google.spanner.v1.GetS" + + "essionRequest\032\032.google.spanner.v1.Sessio" + + "n\"G\332A\004name\202\323\344\223\002:\0228/v1/{name=projects/*/i" + + "nstances/*/databases/*/sessions/*}\022\256\001\n\014L" + + "istSessions\022&.google.spanner.v1.ListSess" + + "ionsRequest\032\'.google.spanner.v1.ListSess" + + "ionsResponse\"M\332A\010database\202\323\344\223\002<\022:/v1/{da" + + "tabase=projects/*/instances/*/databases/" + + "*}/sessions\022\231\001\n\rDeleteSession\022\'.google.s" + + "panner.v1.DeleteSessionRequest\032\026.google." + + "protobuf.Empty\"G\332A\004name\202\323\344\223\002:*8/v1/{name" + + "=projects/*/instances/*/databases/*/sess" + + "ions/*}\022\243\001\n\nExecuteSql\022$.google.spanner." + + "v1.ExecuteSqlRequest\032\034.google.spanner.v1" + + ".ResultSet\"Q\202\323\344\223\002K\"F/v1/{session=project" + + "s/*/instances/*/databases/*/sessions/*}:" + + "executeSql:\001*\022\276\001\n\023ExecuteStreamingSql\022$." + + "google.spanner.v1.ExecuteSqlRequest\032#.go" + + "ogle.spanner.v1.PartialResultSet\"Z\202\323\344\223\002T" + + "\"O/v1/{session=projects/*/instances/*/da" + + "tabases/*/sessions/*}:executeStreamingSq" + + "l:\001*0\001\022\300\001\n\017ExecuteBatchDml\022).google.span" + + "ner.v1.ExecuteBatchDmlRequest\032*.google.s" + + "panner.v1.ExecuteBatchDmlResponse\"V\202\323\344\223\002" + + "P\"K/v1/{session=projects/*/instances/*/d" + + "atabases/*/sessions/*}:executeBatchDml:\001" + + "*\022\221\001\n\004Read\022\036.google.spanner.v1.ReadReque" + + "st\032\034.google.spanner.v1.ResultSet\"K\202\323\344\223\002E" + + "\"@/v1/{session=projects/*/instances/*/da" + + "tabases/*/sessions/*}:read:\001*\022\254\001\n\rStream" + + "ingRead\022\036.google.spanner.v1.ReadRequest\032" + + "#.google.spanner.v1.PartialResultSet\"T\202\323" + + "\344\223\002N\"I/v1/{session=projects/*/instances/" + + "*/databases/*/sessions/*}:streamingRead:" + + "\001*0\001\022\311\001\n\020BeginTransaction\022*.google.spann" + + "er.v1.BeginTransactionRequest\032\036.google.s" + + "panner.v1.Transaction\"i\332A\017session,option" + + "s\202\323\344\223\002Q\"L/v1/{session=projects/*/instanc" + + "es/*/databases/*/sessions/*}:beginTransa" + + "ction:\001*\022\353\001\n\006Commit\022 .google.spanner.v1." + + "CommitRequest\032!.google.spanner.v1.Commit" + + "Response\"\233\001\332A session,transaction_id,mut" + + "ations\332A(session,single_use_transaction," + + "mutations\202\323\344\223\002G\"B/v1/{session=projects/*" + + "/instances/*/databases/*/sessions/*}:com" + + "mit:\001*\022\260\001\n\010Rollback\022\".google.spanner.v1." + + "RollbackRequest\032\026.google.protobuf.Empty\"" + + "h\332A\026session,transaction_id\202\323\344\223\002I\"D/v1/{s" + + "ession=projects/*/instances/*/databases/" + + "*/sessions/*}:rollback:\001*\022\267\001\n\016PartitionQ" + + "uery\022(.google.spanner.v1.PartitionQueryR" + + "equest\032$.google.spanner.v1.PartitionResp" + + "onse\"U\202\323\344\223\002O\"J/v1/{session=projects/*/in" + + "stances/*/databases/*/sessions/*}:partit" + + "ionQuery:\001*\022\264\001\n\rPartitionRead\022\'.google.s" + + "panner.v1.PartitionReadRequest\032$.google." + + "spanner.v1.PartitionResponse\"T\202\323\344\223\002N\"I/v" + "1/{session=projects/*/instances/*/databa" - + "ses/*/sessions/*}:commit:\001*\022\260\001\n\010Rollback" - + "\022\".google.spanner.v1.RollbackRequest\032\026.g" - + "oogle.protobuf.Empty\"h\332A\026session,transac" - + "tion_id\202\323\344\223\002I\"D/v1/{session=projects/*/i" - + "nstances/*/databases/*/sessions/*}:rollb" - + "ack:\001*\022\267\001\n\016PartitionQuery\022(.google.spann" - + "er.v1.PartitionQueryRequest\032$.google.spa" - + "nner.v1.PartitionResponse\"U\202\323\344\223\002O\"J/v1/{" - + "session=projects/*/instances/*/databases" - + "/*/sessions/*}:partitionQuery:\001*\022\264\001\n\rPar" - + "titionRead\022\'.google.spanner.v1.Partition" - + "ReadRequest\032$.google.spanner.v1.Partitio" - + "nResponse\"T\202\323\344\223\002N\"I/v1/{session=projects" - + "/*/instances/*/databases/*/sessions/*}:p" - + "artitionRead:\001*\022\310\001\n\nBatchWrite\022$.google." - + "spanner.v1.BatchWriteRequest\032%.google.sp" - + "anner.v1.BatchWriteResponse\"k\332A\027session," - + "mutation_groups\202\323\344\223\002K\"F/v1/{session=proj" - + "ects/*/instances/*/databases/*/sessions/" - + "*}:batchWrite:\001*0\001\032w\312A\026spanner.googleapi" - + "s.com\322A[https://www.googleapis.com/auth/" - + "cloud-platform,https://www.googleapis.co" - + "m/auth/spanner.dataB\221\002\n\025com.google.spann" - + "er.v1B\014SpannerProtoP\001Z5cloud.google.com/" - + "go/spanner/apiv1/spannerpb;spannerpb\252\002\027G" - + "oogle.Cloud.Spanner.V1\312\002\027Google\\Cloud\\Sp" - + "anner\\V1\352\002\032Google::Cloud::Spanner::V1\352A_" - + "\n\037spanner.googleapis.com/Database\022 com.google.cloud google-cloud-spanner - 6.81.2 + 6.82.0
diff --git a/samples/snippets/src/main/java/com/example/spanner/CopyBackupWithMultiRegionEncryptionKey.java b/samples/snippets/src/main/java/com/example/spanner/CopyBackupWithMultiRegionEncryptionKey.java new file mode 100644 index 00000000000..4fe60a775e5 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/CopyBackupWithMultiRegionEncryptionKey.java @@ -0,0 +1,125 @@ +/* + * Copyright 2024 Google Inc. + * + * 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.example.spanner; + +// [START spanner_copy_backup_with_MR_CMEK] + +import com.google.cloud.Timestamp; +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.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.Backup; +import com.google.spanner.admin.database.v1.BackupName; +import com.google.spanner.admin.database.v1.CopyBackupEncryptionConfig; +import com.google.spanner.admin.database.v1.CopyBackupEncryptionConfig.EncryptionType; +import com.google.spanner.admin.database.v1.CopyBackupRequest; +import com.google.spanner.admin.database.v1.InstanceName; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +public class CopyBackupWithMultiRegionEncryptionKey { + + static void copyBackupWithMultiRegionEncryptionKey() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String sourceBackupId = "my-backup"; + String destinationBackupId = "my-destination-backup"; + String[] kmsKeyNames = + new String[] { + "projects/" + projectId + "/locations//keyRings//cryptoKeys/", + "projects/" + projectId + "/locations//keyRings//cryptoKeys/", + "projects/" + projectId + "/locations//keyRings//cryptoKeys/" + }; + + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService(); + DatabaseAdminClient databaseAdminClient = spanner.createDatabaseAdminClient()) { + copyBackupWithMultiRegionEncryptionKey( + databaseAdminClient, + projectId, + instanceId, + sourceBackupId, + destinationBackupId, + kmsKeyNames); + } + } + + static void copyBackupWithMultiRegionEncryptionKey( + DatabaseAdminClient databaseAdminClient, + String projectId, + String instanceId, + String sourceBackupId, + String destinationBackupId, + String[] kmsKeyNames) { + + Timestamp expireTime = + Timestamp.ofTimeMicroseconds( + TimeUnit.MICROSECONDS.convert( + System.currentTimeMillis() + TimeUnit.DAYS.toMillis(14), TimeUnit.MILLISECONDS)); + + // Initiate the request which returns an OperationFuture. + System.out.println("Copying backup [" + destinationBackupId + "]..."); + CopyBackupRequest request = + CopyBackupRequest.newBuilder() + .setParent(InstanceName.of(projectId, instanceId).toString()) + .setBackupId(destinationBackupId) + .setSourceBackup(BackupName.of(projectId, instanceId, sourceBackupId).toString()) + .setExpireTime(expireTime.toProto()) + .setEncryptionConfig( + CopyBackupEncryptionConfig.newBuilder() + .setEncryptionType(EncryptionType.CUSTOMER_MANAGED_ENCRYPTION) + .addAllKmsKeyNames(ImmutableList.copyOf(kmsKeyNames)) + .build()) + .build(); + Backup destinationBackup; + try { + // Creates a copy of an existing backup. + // Wait for the backup operation to complete. + destinationBackup = databaseAdminClient.copyBackupAsync(request).get(); + System.out.println("Copied backup [" + destinationBackup.getName() + "]"); + } catch (ExecutionException e) { + throw (SpannerException) e.getCause(); + } catch (InterruptedException e) { + throw SpannerExceptionFactory.propagateInterrupt(e); + } + // Load the metadata of the new backup from the server. + destinationBackup = databaseAdminClient.getBackup(destinationBackup.getName()); + System.out.println( + String.format( + "Backup %s of size %d bytes was copied at %s for version of database at %s", + destinationBackup.getName(), + destinationBackup.getSizeBytes(), + OffsetDateTime.ofInstant( + Instant.ofEpochSecond( + destinationBackup.getCreateTime().getSeconds(), + destinationBackup.getCreateTime().getNanos()), + ZoneId.systemDefault()), + OffsetDateTime.ofInstant( + Instant.ofEpochSecond( + destinationBackup.getVersionTime().getSeconds(), + destinationBackup.getVersionTime().getNanos()), + ZoneId.systemDefault()))); + } +} +// [END spanner_copy_backup_with_MR_CMEK] diff --git a/samples/snippets/src/main/java/com/example/spanner/CreateBackupWithMultiRegionEncryptionKey.java b/samples/snippets/src/main/java/com/example/spanner/CreateBackupWithMultiRegionEncryptionKey.java new file mode 100644 index 00000000000..eb8f669deda --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/CreateBackupWithMultiRegionEncryptionKey.java @@ -0,0 +1,123 @@ +/* + * Copyright 2024 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.example.spanner; + +// [START spanner_create_backup_with_MR_CMEK] + +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.protobuf.Timestamp; +import com.google.spanner.admin.database.v1.Backup; +import com.google.spanner.admin.database.v1.BackupName; +import com.google.spanner.admin.database.v1.CreateBackupEncryptionConfig; +import com.google.spanner.admin.database.v1.CreateBackupEncryptionConfig.EncryptionType; +import com.google.spanner.admin.database.v1.CreateBackupRequest; +import com.google.spanner.admin.database.v1.DatabaseName; +import com.google.spanner.admin.database.v1.InstanceName; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.threeten.bp.LocalDateTime; +import org.threeten.bp.OffsetDateTime; + +public class CreateBackupWithMultiRegionEncryptionKey { + + static void createBackupWithMultiRegionEncryptionKey() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + String backupId = "my-backup"; + String[] kmsKeyNames = + new String[] { + "projects/" + projectId + "/locations//keyRings//cryptoKeys/", + "projects/" + projectId + "/locations//keyRings//cryptoKeys/", + "projects/" + projectId + "/locations//keyRings//cryptoKeys/" + }; + + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService(); + DatabaseAdminClient adminClient = spanner.createDatabaseAdminClient()) { + createBackupWithMultiRegionEncryptionKey( + adminClient, projectId, instanceId, databaseId, backupId, kmsKeyNames); + } + } + + static Void createBackupWithMultiRegionEncryptionKey( + DatabaseAdminClient adminClient, + String projectId, + String instanceId, + String databaseId, + String backupId, + String[] kmsKeyNames) { + // Set expire time to 14 days from now. + final Timestamp expireTime = + Timestamp.newBuilder() + .setSeconds( + TimeUnit.MILLISECONDS.toSeconds( + (System.currentTimeMillis() + TimeUnit.DAYS.toMillis(14)))) + .build(); + final BackupName backupName = BackupName.of(projectId, instanceId, backupId); + Backup backup = + Backup.newBuilder() + .setName(backupName.toString()) + .setDatabase(DatabaseName.of(projectId, instanceId, databaseId).toString()) + .setExpireTime(expireTime) + .build(); + + final CreateBackupRequest request = + CreateBackupRequest.newBuilder() + .setParent(InstanceName.of(projectId, instanceId).toString()) + .setBackupId(backupId) + .setBackup(backup) + .setEncryptionConfig( + CreateBackupEncryptionConfig.newBuilder() + .setEncryptionType(EncryptionType.CUSTOMER_MANAGED_ENCRYPTION) + .addAllKmsKeyNames(ImmutableList.copyOf(kmsKeyNames)) + .build()) + .build(); + try { + System.out.println("Waiting for operation to complete..."); + backup = adminClient.createBackupAsync(request).get(1200, TimeUnit.SECONDS); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } catch (TimeoutException e) { + // If the operation timed out propagates the timeout + throw SpannerExceptionFactory.propagateTimeout(e); + } + System.out.printf( + "Backup %s of size %d bytes was created at %s using encryption keys %s%n", + backup.getName(), + backup.getSizeBytes(), + LocalDateTime.ofEpochSecond( + backup.getCreateTime().getSeconds(), + backup.getCreateTime().getNanos(), + OffsetDateTime.now().getOffset()), + ImmutableList.copyOf(kmsKeyNames)); + + return null; + } +} +// [END spanner_create_backup_with_MR_CMEK] diff --git a/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithMultiRegionEncryptionKey.java b/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithMultiRegionEncryptionKey.java new file mode 100644 index 00000000000..962b5b1d5d0 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/CreateDatabaseWithMultiRegionEncryptionKey.java @@ -0,0 +1,106 @@ +/* + * Copyright 2024 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.example.spanner; + +// [START spanner_create_database_with_MR_CMEK] + +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.CreateDatabaseRequest; +import com.google.spanner.admin.database.v1.Database; +import com.google.spanner.admin.database.v1.EncryptionConfig; +import com.google.spanner.admin.database.v1.InstanceName; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class CreateDatabaseWithMultiRegionEncryptionKey { + + static void createDatabaseWithEncryptionKey() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + String[] kmsKeyNames = + new String[] { + "projects/" + projectId + "/locations//keyRings//cryptoKeys/", + "projects/" + projectId + "/locations//keyRings//cryptoKeys/", + "projects/" + projectId + "/locations//keyRings//cryptoKeys/" + }; + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService(); + DatabaseAdminClient adminClient = spanner.createDatabaseAdminClient()) { + createDatabaseWithMultiRegionEncryptionKey( + adminClient, projectId, instanceId, databaseId, kmsKeyNames); + } + } + + static void createDatabaseWithMultiRegionEncryptionKey( + DatabaseAdminClient adminClient, + String projectId, + String instanceId, + String databaseId, + String[] kmsKeyNames) { + InstanceName instanceName = InstanceName.of(projectId, instanceId); + CreateDatabaseRequest request = + CreateDatabaseRequest.newBuilder() + .setParent(instanceName.toString()) + .setCreateStatement("CREATE DATABASE `" + databaseId + "`") + .setEncryptionConfig( + EncryptionConfig.newBuilder() + .addAllKmsKeyNames(ImmutableList.copyOf(kmsKeyNames)) + .build()) + .addAllExtraStatements( + ImmutableList.of( + "CREATE TABLE Singers (" + + " SingerId INT64 NOT NULL," + + " FirstName STRING(1024)," + + " LastName STRING(1024)," + + " SingerInfo BYTES(MAX)" + + ") PRIMARY KEY (SingerId)", + "CREATE TABLE Albums (" + + " SingerId INT64 NOT NULL," + + " AlbumId INT64 NOT NULL," + + " AlbumTitle STRING(MAX)" + + ") PRIMARY KEY (SingerId, AlbumId)," + + " INTERLEAVE IN PARENT Singers ON DELETE CASCADE")) + .build(); + try { + System.out.println("Waiting for operation to complete..."); + Database createdDatabase = + adminClient.createDatabaseAsync(request).get(120, TimeUnit.SECONDS); + + System.out.printf( + "Database %s created with encryption keys %s%n", + createdDatabase.getName(), createdDatabase.getEncryptionConfig().getKmsKeyNamesList()); + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } catch (TimeoutException e) { + // If the operation timed out propagates the timeout + throw SpannerExceptionFactory.propagateTimeout(e); + } + } +} +// [END spanner_create_database_with_MR_CMEK] diff --git a/samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithMultiRegionEncryptionKey.java b/samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithMultiRegionEncryptionKey.java new file mode 100644 index 00000000000..a13ff4b8cd0 --- /dev/null +++ b/samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithMultiRegionEncryptionKey.java @@ -0,0 +1,98 @@ +/* + * Copyright 2024 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.example.spanner; + +// [START spanner_restore_backup_with_MR_CMEK] + +import static com.google.spanner.admin.database.v1.RestoreDatabaseEncryptionConfig.EncryptionType.CUSTOMER_MANAGED_ENCRYPTION; + +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerExceptionFactory; +import com.google.cloud.spanner.SpannerOptions; +import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient; +import com.google.common.collect.ImmutableList; +import com.google.spanner.admin.database.v1.BackupName; +import com.google.spanner.admin.database.v1.Database; +import com.google.spanner.admin.database.v1.InstanceName; +import com.google.spanner.admin.database.v1.RestoreDatabaseEncryptionConfig; +import com.google.spanner.admin.database.v1.RestoreDatabaseRequest; +import java.util.concurrent.ExecutionException; + +public class RestoreBackupWithMultiRegionEncryptionKey { + + static void restoreBackupWithMultiRegionEncryptionKey() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String instanceId = "my-instance"; + String databaseId = "my-database"; + String backupId = "my-backup"; + String[] kmsKeyNames = + new String[] { + "projects/" + projectId + "/locations//keyRings//cryptoKeys/", + "projects/" + projectId + "/locations//keyRings//cryptoKeys/", + "projects/" + projectId + "/locations//keyRings//cryptoKeys/" + }; + + try (Spanner spanner = + SpannerOptions.newBuilder().setProjectId(projectId).build().getService(); + DatabaseAdminClient adminClient = spanner.createDatabaseAdminClient()) { + restoreBackupWithMultiRegionEncryptionKey( + adminClient, projectId, instanceId, backupId, databaseId, kmsKeyNames); + } + } + + static Void restoreBackupWithMultiRegionEncryptionKey( + DatabaseAdminClient adminClient, + String projectId, + String instanceId, + String backupId, + String restoreId, + String[] kmsKeyNames) { + RestoreDatabaseRequest request = + RestoreDatabaseRequest.newBuilder() + .setParent(InstanceName.of(projectId, instanceId).toString()) + .setDatabaseId(restoreId) + .setBackup(BackupName.of(projectId, instanceId, backupId).toString()) + .setEncryptionConfig( + RestoreDatabaseEncryptionConfig.newBuilder() + .setEncryptionType(CUSTOMER_MANAGED_ENCRYPTION) + .addAllKmsKeyNames(ImmutableList.copyOf(kmsKeyNames))) + .build(); + Database database; + try { + System.out.println("Waiting for operation to complete..."); + database = adminClient.restoreDatabaseAsync(request).get(); + ; + } catch (ExecutionException e) { + // If the operation failed during execution, expose the cause. + throw SpannerExceptionFactory.asSpannerException(e.getCause()); + } catch (InterruptedException e) { + // Throw when a thread is waiting, sleeping, or otherwise occupied, + // and the thread is interrupted, either before or during the activity. + throw SpannerExceptionFactory.propagateInterrupt(e); + } + + System.out.printf( + "Database %s restored to %s from backup %s using encryption keys %s%n", + database.getRestoreInfo().getBackupInfo().getSourceDatabase(), + database.getName(), + database.getRestoreInfo().getBackupInfo().getBackup(), + database.getEncryptionConfig().getKmsKeyNamesList()); + return null; + } +} +// [END spanner_restore_backup_with_MR_CMEK] diff --git a/synth.metadata b/synth.metadata index 099e30c3689..9622106469d 100644 --- a/synth.metadata +++ b/synth.metadata @@ -88,7 +88,6 @@ ".kokoro/presubmit/java8.cfg", ".kokoro/presubmit/linkage-monitor.cfg", ".kokoro/presubmit/lint.cfg", - ".kokoro/readme.sh", ".kokoro/release/bump_snapshot.cfg", ".kokoro/release/common.cfg", ".kokoro/release/common.sh", diff --git a/versions.txt b/versions.txt index cdd70c7a2ef..745b2174e24 100644 --- a/versions.txt +++ b/versions.txt @@ -1,13 +1,13 @@ # Format: # module:released-version:current-version -proto-google-cloud-spanner-admin-instance-v1:6.81.2:6.81.2 -proto-google-cloud-spanner-v1:6.81.2:6.81.2 -proto-google-cloud-spanner-admin-database-v1:6.81.2:6.81.2 -grpc-google-cloud-spanner-v1:6.81.2:6.81.2 -grpc-google-cloud-spanner-admin-instance-v1:6.81.2:6.81.2 -grpc-google-cloud-spanner-admin-database-v1:6.81.2:6.81.2 -google-cloud-spanner:6.81.2:6.81.2 -google-cloud-spanner-executor:6.81.2:6.81.2 -proto-google-cloud-spanner-executor-v1:6.81.2:6.81.2 -grpc-google-cloud-spanner-executor-v1:6.81.2:6.81.2 +proto-google-cloud-spanner-admin-instance-v1:6.82.0:6.82.0 +proto-google-cloud-spanner-v1:6.82.0:6.82.0 +proto-google-cloud-spanner-admin-database-v1:6.82.0:6.82.0 +grpc-google-cloud-spanner-v1:6.82.0:6.82.0 +grpc-google-cloud-spanner-admin-instance-v1:6.82.0:6.82.0 +grpc-google-cloud-spanner-admin-database-v1:6.82.0:6.82.0 +google-cloud-spanner:6.82.0:6.82.0 +google-cloud-spanner-executor:6.82.0:6.82.0 +proto-google-cloud-spanner-executor-v1:6.82.0:6.82.0 +grpc-google-cloud-spanner-executor-v1:6.82.0:6.82.0