From 3fd33ba9c5fab43ed475ed3cff9d60c008843981 Mon Sep 17 00:00:00 2001 From: cloud-java-bot <122572305+cloud-java-bot@users.noreply.github.com> Date: Tue, 25 Feb 2025 00:47:07 -0500 Subject: [PATCH 01/12] chore: Update generation configuration at Tue Feb 25 02:25:22 UTC 2025 (#3646) * chore: Update generation configuration at Fri Feb 14 02:23:09 UTC 2025 * chore: generate libraries at Fri Feb 14 02:23:50 UTC 2025 * chore: Update generation configuration at Sat Feb 15 02:22:30 UTC 2025 * chore: Update generation configuration at Thu Feb 20 02:24:02 UTC 2025 * chore: Update generation configuration at Fri Feb 21 02:24:15 UTC 2025 * chore: generate libraries at Fri Feb 21 02:24:52 UTC 2025 * chore: Update generation configuration at Sat Feb 22 02:21:39 UTC 2025 * chore: Update generation configuration at Sun Feb 23 02:26:15 UTC 2025 * chore: generate libraries at Sun Feb 23 02:26:47 UTC 2025 * chore: Update generation configuration at Mon Feb 24 02:26:04 UTC 2025 * chore: Update generation configuration at Tue Feb 25 02:25:22 UTC 2025 --------- Co-authored-by: rahul2393 --- README.md | 2 +- generation_config.yaml | 4 +- .../reflect-config.json | 27 + .../reflect-config.json | 18 + .../reflect-config.json | 9 + .../v1/DatabaseAdminClientHttpJsonTest.java | 12 + .../database/v1/DatabaseAdminClientTest.java | 10 + .../spanner/admin/database/v1/Backup.java | 633 +++++++++++++++++ .../database/v1/BackupInstancePartition.java | 637 ++++++++++++++++++ .../v1/BackupInstancePartitionOrBuilder.java | 53 ++ .../admin/database/v1/BackupOrBuilder.java | 79 +++ .../admin/database/v1/BackupProto.java | 190 +++--- .../v1/SpannerDatabaseAdminProto.java | 7 +- .../spanner/admin/database/v1/backup.proto | 16 + .../database/v1/spanner_database_admin.proto | 4 + .../google/spanner/v1/TransactionOptions.java | 385 ++++++++++- .../v1/TransactionOptionsOrBuilder.java | 25 + .../google/spanner/v1/TransactionProto.java | 74 +- .../proto/google/spanner/v1/transaction.proto | 49 +- 19 files changed, 2107 insertions(+), 127 deletions(-) create mode 100644 proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInstancePartition.java create mode 100644 proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInstancePartitionOrBuilder.java diff --git a/README.md b/README.md index 639b0d9925e..5f828e75a23 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.54.0') +implementation platform('com.google.cloud:libraries-bom:26.55.0') implementation 'com.google.cloud:google-cloud-spanner' ``` diff --git a/generation_config.yaml b/generation_config.yaml index 257ca065090..a6a7866d7e2 100644 --- a/generation_config.yaml +++ b/generation_config.yaml @@ -1,6 +1,6 @@ gapic_generator_version: 2.53.0 -googleapis_commitish: 9605bff3d36fbdb1227b26bce68258c5f00815e4 -libraries_bom_version: 26.54.0 +googleapis_commitish: 6bc8e91bf92cc985da5ed0c227b48f12315cb695 +libraries_bom_version: 26.55.0 libraries: - api_shortname: spanner name_pretty: Cloud Spanner diff --git a/google-cloud-spanner-executor/src/main/resources/META-INF/native-image/com.google.cloud.spanner.executor.v1/reflect-config.json b/google-cloud-spanner-executor/src/main/resources/META-INF/native-image/com.google.cloud.spanner.executor.v1/reflect-config.json index 1b9c4de2d83..357035df837 100644 --- a/google-cloud-spanner-executor/src/main/resources/META-INF/native-image/com.google.cloud.spanner.executor.v1/reflect-config.json +++ b/google-cloud-spanner-executor/src/main/resources/META-INF/native-image/com.google.cloud.spanner.executor.v1/reflect-config.json @@ -1781,6 +1781,24 @@ "allDeclaredClasses": true, "allPublicClasses": true }, + { + "name": "com.google.spanner.admin.database.v1.BackupInstancePartition", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.spanner.admin.database.v1.BackupInstancePartition$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, { "name": "com.google.spanner.admin.database.v1.BackupSchedule", "queryAllDeclaredConstructors": true, @@ -6110,6 +6128,15 @@ "allDeclaredClasses": true, "allPublicClasses": true }, + { + "name": "com.google.spanner.v1.TransactionOptions$IsolationLevel", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, { "name": "com.google.spanner.v1.TransactionOptions$PartitionedDml", "queryAllDeclaredConstructors": true, diff --git a/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.admin.database.v1/reflect-config.json b/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.admin.database.v1/reflect-config.json index 3b456d976d0..0d1524fb146 100644 --- a/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.admin.database.v1/reflect-config.json +++ b/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.admin.database.v1/reflect-config.json @@ -1781,6 +1781,24 @@ "allDeclaredClasses": true, "allPublicClasses": true }, + { + "name": "com.google.spanner.admin.database.v1.BackupInstancePartition", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.spanner.admin.database.v1.BackupInstancePartition$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, { "name": "com.google.spanner.admin.database.v1.BackupSchedule", "queryAllDeclaredConstructors": true, diff --git a/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.v1/reflect-config.json b/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.v1/reflect-config.json index bcbb239a5be..20a93919949 100644 --- a/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.v1/reflect-config.json +++ b/google-cloud-spanner/src/main/resources/META-INF/native-image/com.google.cloud.spanner.v1/reflect-config.json @@ -2249,6 +2249,15 @@ "allDeclaredClasses": true, "allPublicClasses": true }, + { + "name": "com.google.spanner.v1.TransactionOptions$IsolationLevel", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, { "name": "com.google.spanner.v1.TransactionOptions$PartitionedDml", "queryAllDeclaredConstructors": true, diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java index 5d476f914a8..26826b4dd8d 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientHttpJsonTest.java @@ -48,6 +48,7 @@ import com.google.protobuf.Timestamp; import com.google.spanner.admin.database.v1.AddSplitPointsResponse; import com.google.spanner.admin.database.v1.Backup; +import com.google.spanner.admin.database.v1.BackupInstancePartition; import com.google.spanner.admin.database.v1.BackupName; import com.google.spanner.admin.database.v1.BackupSchedule; import com.google.spanner.admin.database.v1.BackupScheduleName; @@ -1099,6 +1100,7 @@ public void createBackupTest() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1168,6 +1170,7 @@ public void createBackupTest2() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1237,6 +1240,7 @@ public void copyBackupTest() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1309,6 +1313,7 @@ public void copyBackupTest2() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1381,6 +1386,7 @@ public void copyBackupTest3() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1453,6 +1459,7 @@ public void copyBackupTest4() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1525,6 +1532,7 @@ public void getBackupTest() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); mockService.addResponse(expectedResponse); @@ -1585,6 +1593,7 @@ public void getBackupTest2() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); mockService.addResponse(expectedResponse); @@ -1645,6 +1654,7 @@ public void updateBackupTest() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); mockService.addResponse(expectedResponse); @@ -1667,6 +1677,7 @@ public void updateBackupTest() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); FieldMask updateMask = FieldMask.newBuilder().build(); @@ -1715,6 +1726,7 @@ public void updateBackupExceptionTest() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); FieldMask updateMask = FieldMask.newBuilder().build(); client.updateBackup(backup, updateMask); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java index 2424ad7bc27..fbc20ebbd9b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/database/v1/DatabaseAdminClientTest.java @@ -51,6 +51,7 @@ import com.google.spanner.admin.database.v1.AddSplitPointsRequest; import com.google.spanner.admin.database.v1.AddSplitPointsResponse; import com.google.spanner.admin.database.v1.Backup; +import com.google.spanner.admin.database.v1.BackupInstancePartition; import com.google.spanner.admin.database.v1.BackupName; import com.google.spanner.admin.database.v1.BackupSchedule; import com.google.spanner.admin.database.v1.BackupScheduleName; @@ -1013,6 +1014,7 @@ public void createBackupTest() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1081,6 +1083,7 @@ public void createBackupTest2() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1149,6 +1152,7 @@ public void copyBackupTest() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1221,6 +1225,7 @@ public void copyBackupTest2() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1293,6 +1298,7 @@ public void copyBackupTest3() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1365,6 +1371,7 @@ public void copyBackupTest4() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); Operation resultOperation = Operation.newBuilder() @@ -1437,6 +1444,7 @@ public void getBackupTest() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); mockDatabaseAdmin.addResponse(expectedResponse); @@ -1491,6 +1499,7 @@ public void getBackupTest2() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); mockDatabaseAdmin.addResponse(expectedResponse); @@ -1545,6 +1554,7 @@ public void updateBackupTest() throws Exception { .addAllBackupSchedules(new ArrayList()) .setIncrementalBackupChainId("incrementalBackupChainId1926005216") .setOldestVersionTime(Timestamp.newBuilder().build()) + .addAllInstancePartitions(new ArrayList()) .build(); mockDatabaseAdmin.addResponse(expectedResponse); diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java index 8b0895ebf50..9171639689c 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/Backup.java @@ -48,6 +48,7 @@ private Backup() { referencingBackups_ = com.google.protobuf.LazyStringArrayList.emptyList(); backupSchedules_ = com.google.protobuf.LazyStringArrayList.emptyList(); incrementalBackupChainId_ = ""; + instancePartitions_ = java.util.Collections.emptyList(); } @java.lang.Override @@ -1355,6 +1356,107 @@ public com.google.protobuf.TimestampOrBuilder getOldestVersionTimeOrBuilder() { : oldestVersionTime_; } + public static final int INSTANCE_PARTITIONS_FIELD_NUMBER = 19; + + @SuppressWarnings("serial") + private java.util.List + instancePartitions_; + /** + * + * + *
+   * Output only. The instance partition(s) storing the backup.
+   *
+   * This is the same as the list of the instance partition(s) that the database
+   * had footprint in at the backup's `version_time`.
+   * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + @java.lang.Override + public java.util.List + getInstancePartitionsList() { + return instancePartitions_; + } + /** + * + * + *
+   * Output only. The instance partition(s) storing the backup.
+   *
+   * This is the same as the list of the instance partition(s) that the database
+   * had footprint in at the backup's `version_time`.
+   * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + @java.lang.Override + public java.util.List< + ? extends com.google.spanner.admin.database.v1.BackupInstancePartitionOrBuilder> + getInstancePartitionsOrBuilderList() { + return instancePartitions_; + } + /** + * + * + *
+   * Output only. The instance partition(s) storing the backup.
+   *
+   * This is the same as the list of the instance partition(s) that the database
+   * had footprint in at the backup's `version_time`.
+   * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + @java.lang.Override + public int getInstancePartitionsCount() { + return instancePartitions_.size(); + } + /** + * + * + *
+   * Output only. The instance partition(s) storing the backup.
+   *
+   * This is the same as the list of the instance partition(s) that the database
+   * had footprint in at the backup's `version_time`.
+   * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + @java.lang.Override + public com.google.spanner.admin.database.v1.BackupInstancePartition getInstancePartitions( + int index) { + return instancePartitions_.get(index); + } + /** + * + * + *
+   * Output only. The instance partition(s) storing the backup.
+   *
+   * This is the same as the list of the instance partition(s) that the database
+   * had footprint in at the backup's `version_time`.
+   * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + @java.lang.Override + public com.google.spanner.admin.database.v1.BackupInstancePartitionOrBuilder + getInstancePartitionsOrBuilder(int index) { + return instancePartitions_.get(index); + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -1426,6 +1528,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io if (((bitField0_ & 0x00000020) != 0)) { output.writeMessage(18, getOldestVersionTime()); } + for (int i = 0; i < instancePartitions_.size(); i++) { + output.writeMessage(19, instancePartitions_.get(i)); + } getUnknownFields().writeTo(output); } @@ -1509,6 +1614,10 @@ public int getSerializedSize() { if (((bitField0_ & 0x00000020) != 0)) { size += com.google.protobuf.CodedOutputStream.computeMessageSize(18, getOldestVersionTime()); } + for (int i = 0; i < instancePartitions_.size(); i++) { + size += + com.google.protobuf.CodedOutputStream.computeMessageSize(19, instancePartitions_.get(i)); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -1561,6 +1670,7 @@ public boolean equals(final java.lang.Object obj) { if (hasOldestVersionTime()) { if (!getOldestVersionTime().equals(other.getOldestVersionTime())) return false; } + if (!getInstancePartitionsList().equals(other.getInstancePartitionsList())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -1628,6 +1738,10 @@ public int hashCode() { hash = (37 * hash) + OLDEST_VERSION_TIME_FIELD_NUMBER; hash = (53 * hash) + getOldestVersionTime().hashCode(); } + if (getInstancePartitionsCount() > 0) { + hash = (37 * hash) + INSTANCE_PARTITIONS_FIELD_NUMBER; + hash = (53 * hash) + getInstancePartitionsList().hashCode(); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -1775,6 +1889,7 @@ private void maybeForceBuilderInitialization() { getEncryptionInformationFieldBuilder(); getMaxExpireTimeFieldBuilder(); getOldestVersionTimeFieldBuilder(); + getInstancePartitionsFieldBuilder(); } } @@ -1830,6 +1945,13 @@ public Builder clear() { oldestVersionTimeBuilder_.dispose(); oldestVersionTimeBuilder_ = null; } + if (instancePartitionsBuilder_ == null) { + instancePartitions_ = java.util.Collections.emptyList(); + } else { + instancePartitions_ = null; + instancePartitionsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00040000); return this; } @@ -1875,6 +1997,15 @@ private void buildPartialRepeatedFields(com.google.spanner.admin.database.v1.Bac } else { result.encryptionInformation_ = encryptionInformationBuilder_.build(); } + if (instancePartitionsBuilder_ == null) { + if (((bitField0_ & 0x00040000) != 0)) { + instancePartitions_ = java.util.Collections.unmodifiableList(instancePartitions_); + bitField0_ = (bitField0_ & ~0x00040000); + } + result.instancePartitions_ = instancePartitions_; + } else { + result.instancePartitions_ = instancePartitionsBuilder_.build(); + } } private void buildPartial0(com.google.spanner.admin.database.v1.Backup result) { @@ -2099,6 +2230,33 @@ public Builder mergeFrom(com.google.spanner.admin.database.v1.Backup other) { if (other.hasOldestVersionTime()) { mergeOldestVersionTime(other.getOldestVersionTime()); } + if (instancePartitionsBuilder_ == null) { + if (!other.instancePartitions_.isEmpty()) { + if (instancePartitions_.isEmpty()) { + instancePartitions_ = other.instancePartitions_; + bitField0_ = (bitField0_ & ~0x00040000); + } else { + ensureInstancePartitionsIsMutable(); + instancePartitions_.addAll(other.instancePartitions_); + } + onChanged(); + } + } else { + if (!other.instancePartitions_.isEmpty()) { + if (instancePartitionsBuilder_.isEmpty()) { + instancePartitionsBuilder_.dispose(); + instancePartitionsBuilder_ = null; + instancePartitions_ = other.instancePartitions_; + bitField0_ = (bitField0_ & ~0x00040000); + instancePartitionsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders + ? getInstancePartitionsFieldBuilder() + : null; + } else { + instancePartitionsBuilder_.addAllMessages(other.instancePartitions_); + } + } + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -2245,6 +2403,20 @@ public Builder mergeFrom( bitField0_ |= 0x00020000; break; } // case 146 + case 154: + { + com.google.spanner.admin.database.v1.BackupInstancePartition m = + input.readMessage( + com.google.spanner.admin.database.v1.BackupInstancePartition.parser(), + extensionRegistry); + if (instancePartitionsBuilder_ == null) { + ensureInstancePartitionsIsMutable(); + instancePartitions_.add(m); + } else { + instancePartitionsBuilder_.addMessage(m); + } + break; + } // case 154 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -5721,6 +5893,467 @@ public com.google.protobuf.TimestampOrBuilder getOldestVersionTimeOrBuilder() { return oldestVersionTimeBuilder_; } + private java.util.List + instancePartitions_ = java.util.Collections.emptyList(); + + private void ensureInstancePartitionsIsMutable() { + if (!((bitField0_ & 0x00040000) != 0)) { + instancePartitions_ = + new java.util.ArrayList( + instancePartitions_); + bitField0_ |= 0x00040000; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.google.spanner.admin.database.v1.BackupInstancePartition, + com.google.spanner.admin.database.v1.BackupInstancePartition.Builder, + com.google.spanner.admin.database.v1.BackupInstancePartitionOrBuilder> + instancePartitionsBuilder_; + + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public java.util.List + getInstancePartitionsList() { + if (instancePartitionsBuilder_ == null) { + return java.util.Collections.unmodifiableList(instancePartitions_); + } else { + return instancePartitionsBuilder_.getMessageList(); + } + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public int getInstancePartitionsCount() { + if (instancePartitionsBuilder_ == null) { + return instancePartitions_.size(); + } else { + return instancePartitionsBuilder_.getCount(); + } + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public com.google.spanner.admin.database.v1.BackupInstancePartition getInstancePartitions( + int index) { + if (instancePartitionsBuilder_ == null) { + return instancePartitions_.get(index); + } else { + return instancePartitionsBuilder_.getMessage(index); + } + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder setInstancePartitions( + int index, com.google.spanner.admin.database.v1.BackupInstancePartition value) { + if (instancePartitionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureInstancePartitionsIsMutable(); + instancePartitions_.set(index, value); + onChanged(); + } else { + instancePartitionsBuilder_.setMessage(index, value); + } + return this; + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder setInstancePartitions( + int index, + com.google.spanner.admin.database.v1.BackupInstancePartition.Builder builderForValue) { + if (instancePartitionsBuilder_ == null) { + ensureInstancePartitionsIsMutable(); + instancePartitions_.set(index, builderForValue.build()); + onChanged(); + } else { + instancePartitionsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder addInstancePartitions( + com.google.spanner.admin.database.v1.BackupInstancePartition value) { + if (instancePartitionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureInstancePartitionsIsMutable(); + instancePartitions_.add(value); + onChanged(); + } else { + instancePartitionsBuilder_.addMessage(value); + } + return this; + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder addInstancePartitions( + int index, com.google.spanner.admin.database.v1.BackupInstancePartition value) { + if (instancePartitionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureInstancePartitionsIsMutable(); + instancePartitions_.add(index, value); + onChanged(); + } else { + instancePartitionsBuilder_.addMessage(index, value); + } + return this; + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder addInstancePartitions( + com.google.spanner.admin.database.v1.BackupInstancePartition.Builder builderForValue) { + if (instancePartitionsBuilder_ == null) { + ensureInstancePartitionsIsMutable(); + instancePartitions_.add(builderForValue.build()); + onChanged(); + } else { + instancePartitionsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder addInstancePartitions( + int index, + com.google.spanner.admin.database.v1.BackupInstancePartition.Builder builderForValue) { + if (instancePartitionsBuilder_ == null) { + ensureInstancePartitionsIsMutable(); + instancePartitions_.add(index, builderForValue.build()); + onChanged(); + } else { + instancePartitionsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder addAllInstancePartitions( + java.lang.Iterable + values) { + if (instancePartitionsBuilder_ == null) { + ensureInstancePartitionsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll(values, instancePartitions_); + onChanged(); + } else { + instancePartitionsBuilder_.addAllMessages(values); + } + return this; + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder clearInstancePartitions() { + if (instancePartitionsBuilder_ == null) { + instancePartitions_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00040000); + onChanged(); + } else { + instancePartitionsBuilder_.clear(); + } + return this; + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public Builder removeInstancePartitions(int index) { + if (instancePartitionsBuilder_ == null) { + ensureInstancePartitionsIsMutable(); + instancePartitions_.remove(index); + onChanged(); + } else { + instancePartitionsBuilder_.remove(index); + } + return this; + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public com.google.spanner.admin.database.v1.BackupInstancePartition.Builder + getInstancePartitionsBuilder(int index) { + return getInstancePartitionsFieldBuilder().getBuilder(index); + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public com.google.spanner.admin.database.v1.BackupInstancePartitionOrBuilder + getInstancePartitionsOrBuilder(int index) { + if (instancePartitionsBuilder_ == null) { + return instancePartitions_.get(index); + } else { + return instancePartitionsBuilder_.getMessageOrBuilder(index); + } + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public java.util.List< + ? extends com.google.spanner.admin.database.v1.BackupInstancePartitionOrBuilder> + getInstancePartitionsOrBuilderList() { + if (instancePartitionsBuilder_ != null) { + return instancePartitionsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(instancePartitions_); + } + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public com.google.spanner.admin.database.v1.BackupInstancePartition.Builder + addInstancePartitionsBuilder() { + return getInstancePartitionsFieldBuilder() + .addBuilder( + com.google.spanner.admin.database.v1.BackupInstancePartition.getDefaultInstance()); + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public com.google.spanner.admin.database.v1.BackupInstancePartition.Builder + addInstancePartitionsBuilder(int index) { + return getInstancePartitionsFieldBuilder() + .addBuilder( + index, + com.google.spanner.admin.database.v1.BackupInstancePartition.getDefaultInstance()); + } + /** + * + * + *
+     * Output only. The instance partition(s) storing the backup.
+     *
+     * This is the same as the list of the instance partition(s) that the database
+     * had footprint in at the backup's `version_time`.
+     * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + public java.util.List + getInstancePartitionsBuilderList() { + return getInstancePartitionsFieldBuilder().getBuilderList(); + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.google.spanner.admin.database.v1.BackupInstancePartition, + com.google.spanner.admin.database.v1.BackupInstancePartition.Builder, + com.google.spanner.admin.database.v1.BackupInstancePartitionOrBuilder> + getInstancePartitionsFieldBuilder() { + if (instancePartitionsBuilder_ == null) { + instancePartitionsBuilder_ = + new com.google.protobuf.RepeatedFieldBuilderV3< + com.google.spanner.admin.database.v1.BackupInstancePartition, + com.google.spanner.admin.database.v1.BackupInstancePartition.Builder, + com.google.spanner.admin.database.v1.BackupInstancePartitionOrBuilder>( + instancePartitions_, + ((bitField0_ & 0x00040000) != 0), + getParentForChildren(), + isClean()); + instancePartitions_ = null; + } + return instancePartitionsBuilder_; + } + @java.lang.Override public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInstancePartition.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInstancePartition.java new file mode 100644 index 00000000000..ad582b34807 --- /dev/null +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInstancePartition.java @@ -0,0 +1,637 @@ +/* + * Copyright 2025 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/spanner/admin/database/v1/backup.proto + +// Protobuf Java Version: 3.25.5 +package com.google.spanner.admin.database.v1; + +/** + * + * + *
+ * Instance partition information for the backup.
+ * 
+ * + * Protobuf type {@code google.spanner.admin.database.v1.BackupInstancePartition} + */ +public final class BackupInstancePartition extends com.google.protobuf.GeneratedMessageV3 + implements + // @@protoc_insertion_point(message_implements:google.spanner.admin.database.v1.BackupInstancePartition) + BackupInstancePartitionOrBuilder { + private static final long serialVersionUID = 0L; + // Use BackupInstancePartition.newBuilder() to construct. + private BackupInstancePartition(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + + private BackupInstancePartition() { + instancePartition_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance(UnusedPrivateParameter unused) { + return new BackupInstancePartition(); + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.spanner.admin.database.v1.BackupProto + .internal_static_google_spanner_admin_database_v1_BackupInstancePartition_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.spanner.admin.database.v1.BackupProto + .internal_static_google_spanner_admin_database_v1_BackupInstancePartition_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.spanner.admin.database.v1.BackupInstancePartition.class, + com.google.spanner.admin.database.v1.BackupInstancePartition.Builder.class); + } + + public static final int INSTANCE_PARTITION_FIELD_NUMBER = 1; + + @SuppressWarnings("serial") + private volatile java.lang.Object instancePartition_ = ""; + /** + * + * + *
+   * A unique identifier for the instance partition. Values are of the form
+   * `projects/<project>/instances/<instance>/instancePartitions/<instance_partition_id>`
+   * 
+ * + * string instance_partition = 1 [(.google.api.resource_reference) = { ... } + * + * @return The instancePartition. + */ + @java.lang.Override + public java.lang.String getInstancePartition() { + java.lang.Object ref = instancePartition_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + instancePartition_ = s; + return s; + } + } + /** + * + * + *
+   * A unique identifier for the instance partition. Values are of the form
+   * `projects/<project>/instances/<instance>/instancePartitions/<instance_partition_id>`
+   * 
+ * + * string instance_partition = 1 [(.google.api.resource_reference) = { ... } + * + * @return The bytes for instancePartition. + */ + @java.lang.Override + public com.google.protobuf.ByteString getInstancePartitionBytes() { + java.lang.Object ref = instancePartition_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + instancePartition_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(instancePartition_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, instancePartition_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(instancePartition_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, instancePartition_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.google.spanner.admin.database.v1.BackupInstancePartition)) { + return super.equals(obj); + } + com.google.spanner.admin.database.v1.BackupInstancePartition other = + (com.google.spanner.admin.database.v1.BackupInstancePartition) obj; + + if (!getInstancePartition().equals(other.getInstancePartition())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + INSTANCE_PARTITION_FIELD_NUMBER; + hash = (53 * hash) + getInstancePartition().hashCode(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseFrom( + java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseFrom( + java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseFrom( + byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseFrom( + java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseDelimitedFrom( + java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseDelimitedFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseFrom( + com.google.protobuf.CodedInputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + + public static Builder newBuilder( + com.google.spanner.admin.database.v1.BackupInstancePartition prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * + * + *
+   * Instance partition information for the backup.
+   * 
+ * + * Protobuf type {@code google.spanner.admin.database.v1.BackupInstancePartition} + */ + public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder + implements + // @@protoc_insertion_point(builder_implements:google.spanner.admin.database.v1.BackupInstancePartition) + com.google.spanner.admin.database.v1.BackupInstancePartitionOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.spanner.admin.database.v1.BackupProto + .internal_static_google_spanner_admin_database_v1_BackupInstancePartition_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.spanner.admin.database.v1.BackupProto + .internal_static_google_spanner_admin_database_v1_BackupInstancePartition_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.spanner.admin.database.v1.BackupInstancePartition.class, + com.google.spanner.admin.database.v1.BackupInstancePartition.Builder.class); + } + + // Construct using com.google.spanner.admin.database.v1.BackupInstancePartition.newBuilder() + private Builder() {} + + private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + } + + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + instancePartition_ = ""; + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return com.google.spanner.admin.database.v1.BackupProto + .internal_static_google_spanner_admin_database_v1_BackupInstancePartition_descriptor; + } + + @java.lang.Override + public com.google.spanner.admin.database.v1.BackupInstancePartition + getDefaultInstanceForType() { + return com.google.spanner.admin.database.v1.BackupInstancePartition.getDefaultInstance(); + } + + @java.lang.Override + public com.google.spanner.admin.database.v1.BackupInstancePartition build() { + com.google.spanner.admin.database.v1.BackupInstancePartition result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.google.spanner.admin.database.v1.BackupInstancePartition buildPartial() { + com.google.spanner.admin.database.v1.BackupInstancePartition result = + new com.google.spanner.admin.database.v1.BackupInstancePartition(this); + if (bitField0_ != 0) { + buildPartial0(result); + } + onBuilt(); + return result; + } + + private void buildPartial0( + com.google.spanner.admin.database.v1.BackupInstancePartition result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.instancePartition_ = instancePartition_; + } + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.setField(field, value); + } + + @java.lang.Override + public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + + @java.lang.Override + public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.addRepeatedField(field, value); + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.spanner.admin.database.v1.BackupInstancePartition) { + return mergeFrom((com.google.spanner.admin.database.v1.BackupInstancePartition) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.spanner.admin.database.v1.BackupInstancePartition other) { + if (other + == com.google.spanner.admin.database.v1.BackupInstancePartition.getDefaultInstance()) + return this; + if (!other.getInstancePartition().isEmpty()) { + instancePartition_ = other.instancePartition_; + bitField0_ |= 0x00000001; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: + { + instancePartition_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000001; + break; + } // case 10 + default: + { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + private int bitField0_; + + private java.lang.Object instancePartition_ = ""; + /** + * + * + *
+     * A unique identifier for the instance partition. Values are of the form
+     * `projects/<project>/instances/<instance>/instancePartitions/<instance_partition_id>`
+     * 
+ * + * string instance_partition = 1 [(.google.api.resource_reference) = { ... } + * + * @return The instancePartition. + */ + public java.lang.String getInstancePartition() { + java.lang.Object ref = instancePartition_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + instancePartition_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * + * + *
+     * A unique identifier for the instance partition. Values are of the form
+     * `projects/<project>/instances/<instance>/instancePartitions/<instance_partition_id>`
+     * 
+ * + * string instance_partition = 1 [(.google.api.resource_reference) = { ... } + * + * @return The bytes for instancePartition. + */ + public com.google.protobuf.ByteString getInstancePartitionBytes() { + java.lang.Object ref = instancePartition_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + instancePartition_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * + * + *
+     * A unique identifier for the instance partition. Values are of the form
+     * `projects/<project>/instances/<instance>/instancePartitions/<instance_partition_id>`
+     * 
+ * + * string instance_partition = 1 [(.google.api.resource_reference) = { ... } + * + * @param value The instancePartition to set. + * @return This builder for chaining. + */ + public Builder setInstancePartition(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + instancePartition_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * + * + *
+     * A unique identifier for the instance partition. Values are of the form
+     * `projects/<project>/instances/<instance>/instancePartitions/<instance_partition_id>`
+     * 
+ * + * string instance_partition = 1 [(.google.api.resource_reference) = { ... } + * + * @return This builder for chaining. + */ + public Builder clearInstancePartition() { + instancePartition_ = getDefaultInstance().getInstancePartition(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * + * + *
+     * A unique identifier for the instance partition. Values are of the form
+     * `projects/<project>/instances/<instance>/instancePartitions/<instance_partition_id>`
+     * 
+ * + * string instance_partition = 1 [(.google.api.resource_reference) = { ... } + * + * @param value The bytes for instancePartition to set. + * @return This builder for chaining. + */ + public Builder setInstancePartitionBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + instancePartition_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + + @java.lang.Override + public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + // @@protoc_insertion_point(builder_scope:google.spanner.admin.database.v1.BackupInstancePartition) + } + + // @@protoc_insertion_point(class_scope:google.spanner.admin.database.v1.BackupInstancePartition) + private static final com.google.spanner.admin.database.v1.BackupInstancePartition + DEFAULT_INSTANCE; + + static { + DEFAULT_INSTANCE = new com.google.spanner.admin.database.v1.BackupInstancePartition(); + } + + public static com.google.spanner.admin.database.v1.BackupInstancePartition getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + @java.lang.Override + public BackupInstancePartition parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.google.spanner.admin.database.v1.BackupInstancePartition getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } +} diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInstancePartitionOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInstancePartitionOrBuilder.java new file mode 100644 index 00000000000..eb1b19816b9 --- /dev/null +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupInstancePartitionOrBuilder.java @@ -0,0 +1,53 @@ +/* + * Copyright 2025 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/spanner/admin/database/v1/backup.proto + +// Protobuf Java Version: 3.25.5 +package com.google.spanner.admin.database.v1; + +public interface BackupInstancePartitionOrBuilder + extends + // @@protoc_insertion_point(interface_extends:google.spanner.admin.database.v1.BackupInstancePartition) + com.google.protobuf.MessageOrBuilder { + + /** + * + * + *
+   * A unique identifier for the instance partition. Values are of the form
+   * `projects/<project>/instances/<instance>/instancePartitions/<instance_partition_id>`
+   * 
+ * + * string instance_partition = 1 [(.google.api.resource_reference) = { ... } + * + * @return The instancePartition. + */ + java.lang.String getInstancePartition(); + /** + * + * + *
+   * A unique identifier for the instance partition. Values are of the form
+   * `projects/<project>/instances/<instance>/instancePartitions/<instance_partition_id>`
+   * 
+ * + * string instance_partition = 1 [(.google.api.resource_reference) = { ... } + * + * @return The bytes for instancePartition. + */ + com.google.protobuf.ByteString getInstancePartitionBytes(); +} diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java index d30141d6fc3..eb90b03212d 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupOrBuilder.java @@ -895,4 +895,83 @@ com.google.spanner.admin.database.v1.EncryptionInfoOrBuilder getEncryptionInform * */ com.google.protobuf.TimestampOrBuilder getOldestVersionTimeOrBuilder(); + + /** + * + * + *
+   * Output only. The instance partition(s) storing the backup.
+   *
+   * This is the same as the list of the instance partition(s) that the database
+   * had footprint in at the backup's `version_time`.
+   * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + java.util.List + getInstancePartitionsList(); + /** + * + * + *
+   * Output only. The instance partition(s) storing the backup.
+   *
+   * This is the same as the list of the instance partition(s) that the database
+   * had footprint in at the backup's `version_time`.
+   * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + com.google.spanner.admin.database.v1.BackupInstancePartition getInstancePartitions(int index); + /** + * + * + *
+   * Output only. The instance partition(s) storing the backup.
+   *
+   * This is the same as the list of the instance partition(s) that the database
+   * had footprint in at the backup's `version_time`.
+   * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + int getInstancePartitionsCount(); + /** + * + * + *
+   * Output only. The instance partition(s) storing the backup.
+   *
+   * This is the same as the list of the instance partition(s) that the database
+   * had footprint in at the backup's `version_time`.
+   * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + java.util.List + getInstancePartitionsOrBuilderList(); + /** + * + * + *
+   * Output only. The instance partition(s) storing the backup.
+   *
+   * This is the same as the list of the instance partition(s) that the database
+   * had footprint in at the backup's `version_time`.
+   * 
+ * + * + * repeated .google.spanner.admin.database.v1.BackupInstancePartition instance_partitions = 19 [(.google.api.field_behavior) = OUTPUT_ONLY]; + * + */ + com.google.spanner.admin.database.v1.BackupInstancePartitionOrBuilder + getInstancePartitionsOrBuilder(int index); } diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java index 52bac0ab063..5f04fe540cc 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/BackupProto.java @@ -96,6 +96,10 @@ public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry r internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_descriptor; static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_spanner_admin_database_v1_BackupInstancePartition_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_spanner_admin_database_v1_BackupInstancePartition_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { return descriptor; @@ -112,7 +116,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "g/operations.proto\032 google/protobuf/fiel" + "d_mask.proto\032\037google/protobuf/timestamp." + "proto\032-google/spanner/admin/database/v1/" - + "common.proto\"\220\t\n\006Backup\0226\n\010database\030\002 \001(" + + "common.proto\"\355\t\n\006Backup\0226\n\010database\030\002 \001(" + "\tB$\372A!\n\037spanner.googleapis.com/Database\022" + "0\n\014version_time\030\t \001(\0132\032.google.protobuf." + "Timestamp\022/\n\013expire_time\030\003 \001(\0132\032.google." @@ -137,92 +141,97 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "\tB-\340A\003\372A\'\n%spanner.googleapis.com/Backup" + "Schedule\022(\n\033incremental_backup_chain_id\030" + "\021 \001(\tB\003\340A\003\022<\n\023oldest_version_time\030\022 \001(\0132" - + "\032.google.protobuf.TimestampB\003\340A\003\"7\n\005Stat" - + "e\022\025\n\021STATE_UNSPECIFIED\020\000\022\014\n\010CREATING\020\001\022\t" - + "\n\005READY\020\002:\\\352AY\n\035spanner.googleapis.com/B" - + "ackup\0228projects/{project}/instances/{ins" - + "tance}/backups/{backup}\"\205\002\n\023CreateBackup" - + "Request\0227\n\006parent\030\001 \001(\tB\'\340A\002\372A!\n\037spanner" - + ".googleapis.com/Instance\022\026\n\tbackup_id\030\002 " - + "\001(\tB\003\340A\002\022=\n\006backup\030\003 \001(\0132(.google.spanne" - + "r.admin.database.v1.BackupB\003\340A\002\022^\n\021encry" - + "ption_config\030\004 \001(\0132>.google.spanner.admi" - + "n.database.v1.CreateBackupEncryptionConf" - + "igB\003\340A\001\"\370\001\n\024CreateBackupMetadata\0220\n\004name" - + "\030\001 \001(\tB\"\372A\037\n\035spanner.googleapis.com/Back" - + "up\0226\n\010database\030\002 \001(\tB$\372A!\n\037spanner.googl" - + "eapis.com/Database\022E\n\010progress\030\003 \001(\01323.g" - + "oogle.spanner.admin.database.v1.Operatio" - + "nProgress\022/\n\013cancel_time\030\004 \001(\0132\032.google." - + "protobuf.Timestamp\"\266\002\n\021CopyBackupRequest" + + "\032.google.protobuf.TimestampB\003\340A\003\022[\n\023inst" + + "ance_partitions\030\023 \003(\01329.google.spanner.a" + + "dmin.database.v1.BackupInstancePartition" + + "B\003\340A\003\"7\n\005State\022\025\n\021STATE_UNSPECIFIED\020\000\022\014\n" + + "\010CREATING\020\001\022\t\n\005READY\020\002:\\\352AY\n\035spanner.goo" + + "gleapis.com/Backup\0228projects/{project}/i" + + "nstances/{instance}/backups/{backup}\"\205\002\n" + + "\023CreateBackupRequest\0227\n\006parent\030\001 \001(\tB\'\340A" + + "\002\372A!\n\037spanner.googleapis.com/Instance\022\026\n" + + "\tbackup_id\030\002 \001(\tB\003\340A\002\022=\n\006backup\030\003 \001(\0132(." + + "google.spanner.admin.database.v1.BackupB" + + "\003\340A\002\022^\n\021encryption_config\030\004 \001(\0132>.google" + + ".spanner.admin.database.v1.CreateBackupE" + + "ncryptionConfigB\003\340A\001\"\370\001\n\024CreateBackupMet" + + "adata\0220\n\004name\030\001 \001(\tB\"\372A\037\n\035spanner.google" + + "apis.com/Backup\0226\n\010database\030\002 \001(\tB$\372A!\n\037" + + "spanner.googleapis.com/Database\022E\n\010progr" + + "ess\030\003 \001(\01323.google.spanner.admin.databas" + + "e.v1.OperationProgress\022/\n\013cancel_time\030\004 " + + "\001(\0132\032.google.protobuf.Timestamp\"\266\002\n\021Copy" + + "BackupRequest\0227\n\006parent\030\001 \001(\tB\'\340A\002\372A!\n\037s" + + "panner.googleapis.com/Instance\022\026\n\tbackup" + + "_id\030\002 \001(\tB\003\340A\002\022<\n\rsource_backup\030\003 \001(\tB%\340" + + "A\002\372A\037\n\035spanner.googleapis.com/Backup\0224\n\013" + + "expire_time\030\004 \001(\0132\032.google.protobuf.Time" + + "stampB\003\340A\002\022\\\n\021encryption_config\030\005 \001(\0132<." + + "google.spanner.admin.database.v1.CopyBac" + + "kupEncryptionConfigB\003\340A\001\"\371\001\n\022CopyBackupM" + + "etadata\0220\n\004name\030\001 \001(\tB\"\372A\037\n\035spanner.goog" + + "leapis.com/Backup\0229\n\rsource_backup\030\002 \001(\t" + + "B\"\372A\037\n\035spanner.googleapis.com/Backup\022E\n\010" + + "progress\030\003 \001(\01323.google.spanner.admin.da" + + "tabase.v1.OperationProgress\022/\n\013cancel_ti" + + "me\030\004 \001(\0132\032.google.protobuf.Timestamp\"\212\001\n" + + "\023UpdateBackupRequest\022=\n\006backup\030\001 \001(\0132(.g" + + "oogle.spanner.admin.database.v1.BackupB\003" + + "\340A\002\0224\n\013update_mask\030\002 \001(\0132\032.google.protob" + + "uf.FieldMaskB\003\340A\002\"G\n\020GetBackupRequest\0223\n" + + "\004name\030\001 \001(\tB%\340A\002\372A\037\n\035spanner.googleapis." + + "com/Backup\"J\n\023DeleteBackupRequest\0223\n\004nam" + + "e\030\001 \001(\tB%\340A\002\372A\037\n\035spanner.googleapis.com/" + + "Backup\"\204\001\n\022ListBackupsRequest\0227\n\006parent\030" + + "\001 \001(\tB\'\340A\002\372A!\n\037spanner.googleapis.com/In" + + "stance\022\016\n\006filter\030\002 \001(\t\022\021\n\tpage_size\030\003 \001(" + + "\005\022\022\n\npage_token\030\004 \001(\t\"i\n\023ListBackupsResp" + + "onse\0229\n\007backups\030\001 \003(\0132(.google.spanner.a" + + "dmin.database.v1.Backup\022\027\n\017next_page_tok" + + "en\030\002 \001(\t\"\215\001\n\033ListBackupOperationsRequest" + "\0227\n\006parent\030\001 \001(\tB\'\340A\002\372A!\n\037spanner.google" - + "apis.com/Instance\022\026\n\tbackup_id\030\002 \001(\tB\003\340A" - + "\002\022<\n\rsource_backup\030\003 \001(\tB%\340A\002\372A\037\n\035spanne" - + "r.googleapis.com/Backup\0224\n\013expire_time\030\004" - + " \001(\0132\032.google.protobuf.TimestampB\003\340A\002\022\\\n" - + "\021encryption_config\030\005 \001(\0132<.google.spanne" - + "r.admin.database.v1.CopyBackupEncryption" - + "ConfigB\003\340A\001\"\371\001\n\022CopyBackupMetadata\0220\n\004na" - + "me\030\001 \001(\tB\"\372A\037\n\035spanner.googleapis.com/Ba" - + "ckup\0229\n\rsource_backup\030\002 \001(\tB\"\372A\037\n\035spanne" - + "r.googleapis.com/Backup\022E\n\010progress\030\003 \001(" - + "\01323.google.spanner.admin.database.v1.Ope" - + "rationProgress\022/\n\013cancel_time\030\004 \001(\0132\032.go" - + "ogle.protobuf.Timestamp\"\212\001\n\023UpdateBackup" - + "Request\022=\n\006backup\030\001 \001(\0132(.google.spanner" - + ".admin.database.v1.BackupB\003\340A\002\0224\n\013update" - + "_mask\030\002 \001(\0132\032.google.protobuf.FieldMaskB" - + "\003\340A\002\"G\n\020GetBackupRequest\0223\n\004name\030\001 \001(\tB%" - + "\340A\002\372A\037\n\035spanner.googleapis.com/Backup\"J\n" - + "\023DeleteBackupRequest\0223\n\004name\030\001 \001(\tB%\340A\002\372" - + "A\037\n\035spanner.googleapis.com/Backup\"\204\001\n\022Li" - + "stBackupsRequest\0227\n\006parent\030\001 \001(\tB\'\340A\002\372A!" - + "\n\037spanner.googleapis.com/Instance\022\016\n\006fil" - + "ter\030\002 \001(\t\022\021\n\tpage_size\030\003 \001(\005\022\022\n\npage_tok" - + "en\030\004 \001(\t\"i\n\023ListBackupsResponse\0229\n\007backu" - + "ps\030\001 \003(\0132(.google.spanner.admin.database" - + ".v1.Backup\022\027\n\017next_page_token\030\002 \001(\t\"\215\001\n\033" - + "ListBackupOperationsRequest\0227\n\006parent\030\001 " - + "\001(\tB\'\340A\002\372A!\n\037spanner.googleapis.com/Inst" - + "ance\022\016\n\006filter\030\002 \001(\t\022\021\n\tpage_size\030\003 \001(\005\022" - + "\022\n\npage_token\030\004 \001(\t\"j\n\034ListBackupOperati" - + "onsResponse\0221\n\noperations\030\001 \003(\0132\035.google" - + ".longrunning.Operation\022\027\n\017next_page_toke" - + "n\030\002 \001(\t\"\342\001\n\nBackupInfo\0222\n\006backup\030\001 \001(\tB\"" - + "\372A\037\n\035spanner.googleapis.com/Backup\0220\n\014ve" - + "rsion_time\030\004 \001(\0132\032.google.protobuf.Times" - + "tamp\022/\n\013create_time\030\002 \001(\0132\032.google.proto" - + "buf.Timestamp\022=\n\017source_database\030\003 \001(\tB$" - + "\372A!\n\037spanner.googleapis.com/Database\"\237\003\n" - + "\034CreateBackupEncryptionConfig\022k\n\017encrypt" - + "ion_type\030\001 \001(\0162M.google.spanner.admin.da" - + "tabase.v1.CreateBackupEncryptionConfig.E" - + "ncryptionTypeB\003\340A\002\022?\n\014kms_key_name\030\002 \001(\t" - + "B)\340A\001\372A#\n!cloudkms.googleapis.com/Crypto" - + "Key\022@\n\rkms_key_names\030\003 \003(\tB)\340A\001\372A#\n!clou" - + "dkms.googleapis.com/CryptoKey\"\216\001\n\016Encryp" - + "tionType\022\037\n\033ENCRYPTION_TYPE_UNSPECIFIED\020" - + "\000\022\033\n\027USE_DATABASE_ENCRYPTION\020\001\022\035\n\031GOOGLE" - + "_DEFAULT_ENCRYPTION\020\002\022\037\n\033CUSTOMER_MANAGE" - + "D_ENCRYPTION\020\003\"\253\003\n\032CopyBackupEncryptionC" - + "onfig\022i\n\017encryption_type\030\001 \001(\0162K.google." - + "spanner.admin.database.v1.CopyBackupEncr" - + "yptionConfig.EncryptionTypeB\003\340A\002\022?\n\014kms_" - + "key_name\030\002 \001(\tB)\340A\001\372A#\n!cloudkms.googlea" - + "pis.com/CryptoKey\022@\n\rkms_key_names\030\003 \003(\t" - + "B)\340A\001\372A#\n!cloudkms.googleapis.com/Crypto" - + "Key\"\236\001\n\016EncryptionType\022\037\n\033ENCRYPTION_TYP" - + "E_UNSPECIFIED\020\000\022+\n\'USE_CONFIG_DEFAULT_OR" - + "_BACKUP_ENCRYPTION\020\001\022\035\n\031GOOGLE_DEFAULT_E" - + "NCRYPTION\020\002\022\037\n\033CUSTOMER_MANAGED_ENCRYPTI" - + "ON\020\003\"\020\n\016FullBackupSpec\"\027\n\025IncrementalBac" - + "kupSpecB\375\001\n$com.google.spanner.admin.dat" - + "abase.v1B\013BackupProtoP\001ZFcloud.google.co" - + "m/go/spanner/admin/database/apiv1/databa" - + "sepb;databasepb\252\002&Google.Cloud.Spanner.A" - + "dmin.Database.V1\312\002&Google\\Cloud\\Spanner\\" - + "Admin\\Database\\V1\352\002+Google::Cloud::Spann" - + "er::Admin::Database::V1b\006proto3" + + "apis.com/Instance\022\016\n\006filter\030\002 \001(\t\022\021\n\tpag" + + "e_size\030\003 \001(\005\022\022\n\npage_token\030\004 \001(\t\"j\n\034List" + + "BackupOperationsResponse\0221\n\noperations\030\001" + + " \003(\0132\035.google.longrunning.Operation\022\027\n\017n" + + "ext_page_token\030\002 \001(\t\"\342\001\n\nBackupInfo\0222\n\006b" + + "ackup\030\001 \001(\tB\"\372A\037\n\035spanner.googleapis.com" + + "/Backup\0220\n\014version_time\030\004 \001(\0132\032.google.p" + + "rotobuf.Timestamp\022/\n\013create_time\030\002 \001(\0132\032" + + ".google.protobuf.Timestamp\022=\n\017source_dat" + + "abase\030\003 \001(\tB$\372A!\n\037spanner.googleapis.com" + + "/Database\"\237\003\n\034CreateBackupEncryptionConf" + + "ig\022k\n\017encryption_type\030\001 \001(\0162M.google.spa" + + "nner.admin.database.v1.CreateBackupEncry" + + "ptionConfig.EncryptionTypeB\003\340A\002\022?\n\014kms_k" + + "ey_name\030\002 \001(\tB)\340A\001\372A#\n!cloudkms.googleap" + + "is.com/CryptoKey\022@\n\rkms_key_names\030\003 \003(\tB" + + ")\340A\001\372A#\n!cloudkms.googleapis.com/CryptoK" + + "ey\"\216\001\n\016EncryptionType\022\037\n\033ENCRYPTION_TYPE" + + "_UNSPECIFIED\020\000\022\033\n\027USE_DATABASE_ENCRYPTIO" + + "N\020\001\022\035\n\031GOOGLE_DEFAULT_ENCRYPTION\020\002\022\037\n\033CU" + + "STOMER_MANAGED_ENCRYPTION\020\003\"\253\003\n\032CopyBack" + + "upEncryptionConfig\022i\n\017encryption_type\030\001 " + + "\001(\0162K.google.spanner.admin.database.v1.C" + + "opyBackupEncryptionConfig.EncryptionType" + + "B\003\340A\002\022?\n\014kms_key_name\030\002 \001(\tB)\340A\001\372A#\n!clo" + + "udkms.googleapis.com/CryptoKey\022@\n\rkms_ke" + + "y_names\030\003 \003(\tB)\340A\001\372A#\n!cloudkms.googleap" + + "is.com/CryptoKey\"\236\001\n\016EncryptionType\022\037\n\033E" + + "NCRYPTION_TYPE_UNSPECIFIED\020\000\022+\n\'USE_CONF" + + "IG_DEFAULT_OR_BACKUP_ENCRYPTION\020\001\022\035\n\031GOO" + + "GLE_DEFAULT_ENCRYPTION\020\002\022\037\n\033CUSTOMER_MAN" + + "AGED_ENCRYPTION\020\003\"\020\n\016FullBackupSpec\"\027\n\025I" + + "ncrementalBackupSpec\"d\n\027BackupInstancePa" + + "rtition\022I\n\022instance_partition\030\001 \001(\tB-\372A*" + + "\n(spanner.googleapis.com/InstancePartiti" + + "onB\375\001\n$com.google.spanner.admin.database" + + ".v1B\013BackupProtoP\001ZFcloud.google.com/go/" + + "spanner/admin/database/apiv1/databasepb;" + + "databasepb\252\002&Google.Cloud.Spanner.Admin." + + "Database.V1\312\002&Google\\Cloud\\Spanner\\Admin" + + "\\Database\\V1\352\002+Google::Cloud::Spanner::A" + + "dmin::Database::V1b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( @@ -259,6 +268,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { "BackupSchedules", "IncrementalBackupChainId", "OldestVersionTime", + "InstancePartitions", }); internal_static_google_spanner_admin_database_v1_CreateBackupRequest_descriptor = getDescriptor().getMessageTypes().get(1); @@ -384,6 +394,14 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_google_spanner_admin_database_v1_IncrementalBackupSpec_descriptor, new java.lang.String[] {}); + internal_static_google_spanner_admin_database_v1_BackupInstancePartition_descriptor = + getDescriptor().getMessageTypes().get(17); + internal_static_google_spanner_admin_database_v1_BackupInstancePartition_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_google_spanner_admin_database_v1_BackupInstancePartition_descriptor, + new java.lang.String[] { + "InstancePartition", + }); com.google.protobuf.ExtensionRegistry registry = com.google.protobuf.ExtensionRegistry.newInstance(); registry.add(com.google.api.FieldBehaviorProto.fieldBehavior); diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/SpannerDatabaseAdminProto.java b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/SpannerDatabaseAdminProto.java index 06a130a7002..7b9974f3e76 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/SpannerDatabaseAdminProto.java +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/java/com/google/spanner/admin/database/v1/SpannerDatabaseAdminProto.java @@ -461,7 +461,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "ackupSchedules\032x\312A\026spanner.googleapis.co" + "m\322A\\https://www.googleapis.com/auth/clou" + "d-platform,https://www.googleapis.com/au" - + "th/spanner.adminB\330\002\n$com.google.spanner." + + "th/spanner.adminB\326\003\n$com.google.spanner." + "admin.database.v1B\031SpannerDatabaseAdminP" + "rotoP\001ZFcloud.google.com/go/spanner/admi" + "n/database/apiv1/databasepb;databasepb\252\002" @@ -470,7 +470,10 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "\352\002+Google::Cloud::Spanner::Admin::Databa" + "se::V1\352AJ\n\037spanner.googleapis.com/Instan" + "ce\022\'projects/{project}/instances/{instan" - + "ce}b\006proto3" + + "ce}\352A{\n(spanner.googleapis.com/InstanceP" + + "artition\022Oprojects/{project}/instances/{" + + "instance}/instancePartitions/{instance_p" + + "artition}b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup.proto b/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup.proto index f3473f4eabf..54a7be3e33d 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup.proto +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/backup.proto @@ -207,6 +207,13 @@ message Backup { // retained by the backup system. google.protobuf.Timestamp oldest_version_time = 18 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. The instance partition(s) storing the backup. + // + // This is the same as the list of the instance partition(s) that the database + // had footprint in at the backup's `version_time`. + repeated BackupInstancePartition instance_partitions = 19 + [(google.api.field_behavior) = OUTPUT_ONLY]; } // The request for @@ -755,3 +762,12 @@ message FullBackupSpec {} // successive incremental backups. The first backup created for an // incremental backup chain is always a full backup. message IncrementalBackupSpec {} + +// Instance partition information for the backup. +message BackupInstancePartition { + // A unique identifier for the instance partition. Values are of the form + // `projects//instances//instancePartitions/` + string instance_partition = 1 [(google.api.resource_reference) = { + type: "spanner.googleapis.com/InstancePartition" + }]; +} diff --git a/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/spanner_database_admin.proto b/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/spanner_database_admin.proto index 27e3206293e..125196fe9bf 100644 --- a/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/spanner_database_admin.proto +++ b/proto-google-cloud-spanner-admin-database-v1/src/main/proto/google/spanner/admin/database/v1/spanner_database_admin.proto @@ -42,6 +42,10 @@ option (google.api.resource_definition) = { type: "spanner.googleapis.com/Instance" pattern: "projects/{project}/instances/{instance}" }; +option (google.api.resource_definition) = { + type: "spanner.googleapis.com/InstancePartition" + pattern: "projects/{project}/instances/{instance}/instancePartitions/{instance_partition}" +}; // Cloud Spanner Database Admin API // diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptions.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptions.java index a12a8ebdb42..25e1a63c58f 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptions.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptions.java @@ -361,7 +361,9 @@ private TransactionOptions(com.google.protobuf.GeneratedMessageV3.Builder bui super(builder); } - private TransactionOptions() {} + private TransactionOptions() { + isolationLevel_ = 0; + } @java.lang.Override @SuppressWarnings({"unused"}) @@ -384,6 +386,203 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { com.google.spanner.v1.TransactionOptions.Builder.class); } + /** + * + * + *
+   * `IsolationLevel` is used when setting `isolation_level` for a transaction.
+   * 
+ * + * Protobuf enum {@code google.spanner.v1.TransactionOptions.IsolationLevel} + */ + public enum IsolationLevel implements com.google.protobuf.ProtocolMessageEnum { + /** + * + * + *
+     * Default value.
+     *
+     * If the value is not specified, the `SERIALIZABLE` isolation level is
+     * used.
+     * 
+ * + * ISOLATION_LEVEL_UNSPECIFIED = 0; + */ + ISOLATION_LEVEL_UNSPECIFIED(0), + /** + * + * + *
+     * All transactions appear as if they executed in a serial order, even if
+     * some of the reads, writes, and other operations of distinct transactions
+     * actually occurred in parallel. Spanner assigns commit timestamps that
+     * reflect the order of committed transactions to implement this property.
+     * Spanner offers a stronger guarantee than serializability called external
+     * consistency. For further details, please refer to
+     * https://cloud.google.com/spanner/docs/true-time-external-consistency#serializability.
+     * 
+ * + * SERIALIZABLE = 1; + */ + SERIALIZABLE(1), + /** + * + * + *
+     * All reads performed during the transaction observe a consistent snapshot
+     * of the database, and the transaction will only successfully commit in the
+     * absence of conflicts between its updates and any concurrent updates that
+     * have occurred since that snapshot. Consequently, in contrast to
+     * `SERIALIZABLE` transactions, only write-write conflicts are detected in
+     * snapshot transactions.
+     *
+     * This isolation level does not support Read-only and Partitioned DML
+     * transactions.
+     *
+     * When `REPEATABLE_READ` is specified on a read-write transaction, the
+     * locking semantics default to `OPTIMISTIC`.
+     * 
+ * + * REPEATABLE_READ = 2; + */ + REPEATABLE_READ(2), + UNRECOGNIZED(-1), + ; + + /** + * + * + *
+     * Default value.
+     *
+     * If the value is not specified, the `SERIALIZABLE` isolation level is
+     * used.
+     * 
+ * + * ISOLATION_LEVEL_UNSPECIFIED = 0; + */ + public static final int ISOLATION_LEVEL_UNSPECIFIED_VALUE = 0; + /** + * + * + *
+     * All transactions appear as if they executed in a serial order, even if
+     * some of the reads, writes, and other operations of distinct transactions
+     * actually occurred in parallel. Spanner assigns commit timestamps that
+     * reflect the order of committed transactions to implement this property.
+     * Spanner offers a stronger guarantee than serializability called external
+     * consistency. For further details, please refer to
+     * https://cloud.google.com/spanner/docs/true-time-external-consistency#serializability.
+     * 
+ * + * SERIALIZABLE = 1; + */ + public static final int SERIALIZABLE_VALUE = 1; + /** + * + * + *
+     * All reads performed during the transaction observe a consistent snapshot
+     * of the database, and the transaction will only successfully commit in the
+     * absence of conflicts between its updates and any concurrent updates that
+     * have occurred since that snapshot. Consequently, in contrast to
+     * `SERIALIZABLE` transactions, only write-write conflicts are detected in
+     * snapshot transactions.
+     *
+     * This isolation level does not support Read-only and Partitioned DML
+     * transactions.
+     *
+     * When `REPEATABLE_READ` is specified on a read-write transaction, the
+     * locking semantics default to `OPTIMISTIC`.
+     * 
+ * + * REPEATABLE_READ = 2; + */ + public static final int REPEATABLE_READ_VALUE = 2; + + public final int getNumber() { + if (this == UNRECOGNIZED) { + throw new java.lang.IllegalArgumentException( + "Can't get the number of an unknown enum value."); + } + return value; + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static IsolationLevel valueOf(int value) { + return forNumber(value); + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + */ + public static IsolationLevel forNumber(int value) { + switch (value) { + case 0: + return ISOLATION_LEVEL_UNSPECIFIED; + case 1: + return SERIALIZABLE; + case 2: + return REPEATABLE_READ; + default: + return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap internalGetValueMap() { + return internalValueMap; + } + + private static final com.google.protobuf.Internal.EnumLiteMap internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public IsolationLevel findValueByNumber(int number) { + return IsolationLevel.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() { + if (this == UNRECOGNIZED) { + throw new java.lang.IllegalStateException( + "Can't get the descriptor of an unrecognized enum value."); + } + return getDescriptor().getValues().get(ordinal()); + } + + public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() { + return getDescriptor(); + } + + public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { + return com.google.spanner.v1.TransactionOptions.getDescriptor().getEnumTypes().get(0); + } + + private static final IsolationLevel[] VALUES = values(); + + public static IsolationLevel valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException("EnumValueDescriptor is not for this type."); + } + if (desc.getIndex() == -1) { + return UNRECOGNIZED; + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private IsolationLevel(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:google.spanner.v1.TransactionOptions.IsolationLevel) + } + public interface ReadWriteOrBuilder extends // @@protoc_insertion_point(interface_extends:google.spanner.v1.TransactionOptions.ReadWrite) @@ -496,7 +695,17 @@ public enum ReadLockMode implements com.google.protobuf.ProtocolMessageEnum { *
        * Default value.
        *
-       * If the value is not specified, the pessimistic read lock is used.
+       * * If isolation level is `REPEATABLE_READ`, then it is an error to
+       *   specify `read_lock_mode`. Locking semantics default to `OPTIMISTIC`.
+       *   No validation checks are done for reads, except for:
+       *     1. reads done as part of queries that use `SELECT FOR UPDATE`
+       *     2. reads done as part of statements with a `LOCK_SCANNED_RANGES`
+       *        hint
+       *     3. reads done as part of DML statements
+       *   to validate that the data that was served at the snapshot time is
+       *   unchanged at commit time.
+       * * At all other isolation levels, if `read_lock_mode` is the default
+       *   value, then pessimistic read lock is used.
        * 
* * READ_LOCK_MODE_UNSPECIFIED = 0; @@ -509,6 +718,7 @@ public enum ReadLockMode implements com.google.protobuf.ProtocolMessageEnum { * Pessimistic lock mode. * * Read locks are acquired immediately on read. + * Semantics described only applies to `SERIALIZABLE` isolation. * * * PESSIMISTIC = 1; @@ -523,6 +733,7 @@ public enum ReadLockMode implements com.google.protobuf.ProtocolMessageEnum { * Locks for reads within the transaction are not acquired on read. * Instead the locks are acquired on a commit to validate that * read/queried data has not changed since the transaction started. + * Semantics described only applies to `SERIALIZABLE` isolation. * * * OPTIMISTIC = 2; @@ -537,7 +748,17 @@ public enum ReadLockMode implements com.google.protobuf.ProtocolMessageEnum { *
        * Default value.
        *
-       * If the value is not specified, the pessimistic read lock is used.
+       * * If isolation level is `REPEATABLE_READ`, then it is an error to
+       *   specify `read_lock_mode`. Locking semantics default to `OPTIMISTIC`.
+       *   No validation checks are done for reads, except for:
+       *     1. reads done as part of queries that use `SELECT FOR UPDATE`
+       *     2. reads done as part of statements with a `LOCK_SCANNED_RANGES`
+       *        hint
+       *     3. reads done as part of DML statements
+       *   to validate that the data that was served at the snapshot time is
+       *   unchanged at commit time.
+       * * At all other isolation levels, if `read_lock_mode` is the default
+       *   value, then pessimistic read lock is used.
        * 
* * READ_LOCK_MODE_UNSPECIFIED = 0; @@ -550,6 +771,7 @@ public enum ReadLockMode implements com.google.protobuf.ProtocolMessageEnum { * Pessimistic lock mode. * * Read locks are acquired immediately on read. + * Semantics described only applies to `SERIALIZABLE` isolation. * * * PESSIMISTIC = 1; @@ -564,6 +786,7 @@ public enum ReadLockMode implements com.google.protobuf.ProtocolMessageEnum { * Locks for reads within the transaction are not acquired on read. * Instead the locks are acquired on a commit to validate that * read/queried data has not changed since the transaction started. + * Semantics described only applies to `SERIALIZABLE` isolation. * * * OPTIMISTIC = 2; @@ -4777,6 +5000,43 @@ public boolean getExcludeTxnFromChangeStreams() { return excludeTxnFromChangeStreams_; } + public static final int ISOLATION_LEVEL_FIELD_NUMBER = 6; + private int isolationLevel_ = 0; + /** + * + * + *
+   * Isolation level for the transaction.
+   * 
+ * + * .google.spanner.v1.TransactionOptions.IsolationLevel isolation_level = 6; + * + * @return The enum numeric value on the wire for isolationLevel. + */ + @java.lang.Override + public int getIsolationLevelValue() { + return isolationLevel_; + } + /** + * + * + *
+   * Isolation level for the transaction.
+   * 
+ * + * .google.spanner.v1.TransactionOptions.IsolationLevel isolation_level = 6; + * + * @return The isolationLevel. + */ + @java.lang.Override + public com.google.spanner.v1.TransactionOptions.IsolationLevel getIsolationLevel() { + com.google.spanner.v1.TransactionOptions.IsolationLevel result = + com.google.spanner.v1.TransactionOptions.IsolationLevel.forNumber(isolationLevel_); + return result == null + ? com.google.spanner.v1.TransactionOptions.IsolationLevel.UNRECOGNIZED + : result; + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -4803,6 +5063,11 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io if (excludeTxnFromChangeStreams_ != false) { output.writeBool(5, excludeTxnFromChangeStreams_); } + if (isolationLevel_ + != com.google.spanner.v1.TransactionOptions.IsolationLevel.ISOLATION_LEVEL_UNSPECIFIED + .getNumber()) { + output.writeEnum(6, isolationLevel_); + } getUnknownFields().writeTo(output); } @@ -4831,6 +5096,11 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream.computeBoolSize(5, excludeTxnFromChangeStreams_); } + if (isolationLevel_ + != com.google.spanner.v1.TransactionOptions.IsolationLevel.ISOLATION_LEVEL_UNSPECIFIED + .getNumber()) { + size += com.google.protobuf.CodedOutputStream.computeEnumSize(6, isolationLevel_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -4847,6 +5117,7 @@ public boolean equals(final java.lang.Object obj) { com.google.spanner.v1.TransactionOptions other = (com.google.spanner.v1.TransactionOptions) obj; if (getExcludeTxnFromChangeStreams() != other.getExcludeTxnFromChangeStreams()) return false; + if (isolationLevel_ != other.isolationLevel_) return false; if (!getModeCase().equals(other.getModeCase())) return false; switch (modeCase_) { case 1: @@ -4874,6 +5145,8 @@ public int hashCode() { hash = (19 * hash) + getDescriptor().hashCode(); hash = (37 * hash) + EXCLUDE_TXN_FROM_CHANGE_STREAMS_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(getExcludeTxnFromChangeStreams()); + hash = (37 * hash) + ISOLATION_LEVEL_FIELD_NUMBER; + hash = (53 * hash) + isolationLevel_; switch (modeCase_) { case 1: hash = (37 * hash) + READ_WRITE_FIELD_NUMBER; @@ -5362,6 +5635,7 @@ public Builder clear() { readOnlyBuilder_.clear(); } excludeTxnFromChangeStreams_ = false; + isolationLevel_ = 0; modeCase_ = 0; mode_ = null; return this; @@ -5404,6 +5678,9 @@ private void buildPartial0(com.google.spanner.v1.TransactionOptions result) { if (((from_bitField0_ & 0x00000008) != 0)) { result.excludeTxnFromChangeStreams_ = excludeTxnFromChangeStreams_; } + if (((from_bitField0_ & 0x00000010) != 0)) { + result.isolationLevel_ = isolationLevel_; + } } private void buildPartialOneofs(com.google.spanner.v1.TransactionOptions result) { @@ -5468,6 +5745,9 @@ public Builder mergeFrom(com.google.spanner.v1.TransactionOptions other) { if (other.getExcludeTxnFromChangeStreams() != false) { setExcludeTxnFromChangeStreams(other.getExcludeTxnFromChangeStreams()); } + if (other.isolationLevel_ != 0) { + setIsolationLevelValue(other.getIsolationLevelValue()); + } switch (other.getModeCase()) { case READ_WRITE: { @@ -5539,6 +5819,12 @@ public Builder mergeFrom( bitField0_ |= 0x00000008; break; } // case 40 + case 48: + { + isolationLevel_ = input.readEnum(); + bitField0_ |= 0x00000010; + break; + } // case 48 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -6404,6 +6690,99 @@ public Builder clearExcludeTxnFromChangeStreams() { return this; } + private int isolationLevel_ = 0; + /** + * + * + *
+     * Isolation level for the transaction.
+     * 
+ * + * .google.spanner.v1.TransactionOptions.IsolationLevel isolation_level = 6; + * + * @return The enum numeric value on the wire for isolationLevel. + */ + @java.lang.Override + public int getIsolationLevelValue() { + return isolationLevel_; + } + /** + * + * + *
+     * Isolation level for the transaction.
+     * 
+ * + * .google.spanner.v1.TransactionOptions.IsolationLevel isolation_level = 6; + * + * @param value The enum numeric value on the wire for isolationLevel to set. + * @return This builder for chaining. + */ + public Builder setIsolationLevelValue(int value) { + isolationLevel_ = value; + bitField0_ |= 0x00000010; + onChanged(); + return this; + } + /** + * + * + *
+     * Isolation level for the transaction.
+     * 
+ * + * .google.spanner.v1.TransactionOptions.IsolationLevel isolation_level = 6; + * + * @return The isolationLevel. + */ + @java.lang.Override + public com.google.spanner.v1.TransactionOptions.IsolationLevel getIsolationLevel() { + com.google.spanner.v1.TransactionOptions.IsolationLevel result = + com.google.spanner.v1.TransactionOptions.IsolationLevel.forNumber(isolationLevel_); + return result == null + ? com.google.spanner.v1.TransactionOptions.IsolationLevel.UNRECOGNIZED + : result; + } + /** + * + * + *
+     * Isolation level for the transaction.
+     * 
+ * + * .google.spanner.v1.TransactionOptions.IsolationLevel isolation_level = 6; + * + * @param value The isolationLevel to set. + * @return This builder for chaining. + */ + public Builder setIsolationLevel( + com.google.spanner.v1.TransactionOptions.IsolationLevel value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + isolationLevel_ = value.getNumber(); + onChanged(); + return this; + } + /** + * + * + *
+     * Isolation level for the transaction.
+     * 
+ * + * .google.spanner.v1.TransactionOptions.IsolationLevel isolation_level = 6; + * + * @return This builder for chaining. + */ + public Builder clearIsolationLevel() { + bitField0_ = (bitField0_ & ~0x00000010); + isolationLevel_ = 0; + 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/TransactionOptionsOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptionsOrBuilder.java index fff95012eed..07566e10592 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptionsOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionOptionsOrBuilder.java @@ -191,5 +191,30 @@ public interface TransactionOptionsOrBuilder */ boolean getExcludeTxnFromChangeStreams(); + /** + * + * + *
+   * Isolation level for the transaction.
+   * 
+ * + * .google.spanner.v1.TransactionOptions.IsolationLevel isolation_level = 6; + * + * @return The enum numeric value on the wire for isolationLevel. + */ + int getIsolationLevelValue(); + /** + * + * + *
+   * Isolation level for the transaction.
+   * 
+ * + * .google.spanner.v1.TransactionOptions.IsolationLevel isolation_level = 6; + * + * @return The isolationLevel. + */ + com.google.spanner.v1.TransactionOptions.IsolationLevel getIsolationLevel(); + com.google.spanner.v1.TransactionOptions.ModeCase getModeCase(); } diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionProto.java index 4e94598f9b1..7c8b6760bdc 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/TransactionProto.java @@ -68,43 +68,48 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { "\n#google/spanner/v1/transaction.proto\022\021g" + "oogle.spanner.v1\032\037google/api/field_behav" + "ior.proto\032\036google/protobuf/duration.prot" - + "o\032\037google/protobuf/timestamp.proto\"\316\006\n\022T" + + "o\032\037google/protobuf/timestamp.proto\"\367\007\n\022T" + "ransactionOptions\022E\n\nread_write\030\001 \001(\0132/." + "google.spanner.v1.TransactionOptions.Rea" + "dWriteH\000\022O\n\017partitioned_dml\030\003 \001(\01324.goog" + "le.spanner.v1.TransactionOptions.Partiti" + "onedDmlH\000\022C\n\tread_only\030\002 \001(\0132..google.sp" + "anner.v1.TransactionOptions.ReadOnlyH\000\022\'" - + "\n\037exclude_txn_from_change_streams\030\005 \001(\010\032" - + "\354\001\n\tReadWrite\022T\n\016read_lock_mode\030\001 \001(\0162<." - + "google.spanner.v1.TransactionOptions.Rea" - + "dWrite.ReadLockMode\0228\n+multiplexed_sessi" - + "on_previous_transaction_id\030\002 \001(\014B\003\340A\001\"O\n" - + "\014ReadLockMode\022\036\n\032READ_LOCK_MODE_UNSPECIF" - + "IED\020\000\022\017\n\013PESSIMISTIC\020\001\022\016\n\nOPTIMISTIC\020\002\032\020" - + "\n\016PartitionedDml\032\250\002\n\010ReadOnly\022\020\n\006strong\030" - + "\001 \001(\010H\000\0228\n\022min_read_timestamp\030\002 \001(\0132\032.go" - + "ogle.protobuf.TimestampH\000\0222\n\rmax_stalene" - + "ss\030\003 \001(\0132\031.google.protobuf.DurationH\000\0224\n" - + "\016read_timestamp\030\004 \001(\0132\032.google.protobuf." - + "TimestampH\000\0224\n\017exact_staleness\030\005 \001(\0132\031.g" - + "oogle.protobuf.DurationH\000\022\035\n\025return_read" - + "_timestamp\030\006 \001(\010B\021\n\017timestamp_boundB\006\n\004m" - + "ode\"\233\001\n\013Transaction\022\n\n\002id\030\001 \001(\014\0222\n\016read_" - + "timestamp\030\002 \001(\0132\032.google.protobuf.Timest" - + "amp\022L\n\017precommit_token\030\003 \001(\01323.google.sp" - + "anner.v1.MultiplexedSessionPrecommitToke" - + "n\"\244\001\n\023TransactionSelector\022;\n\nsingle_use\030" - + "\001 \001(\0132%.google.spanner.v1.TransactionOpt" - + "ionsH\000\022\014\n\002id\030\002 \001(\014H\000\0226\n\005begin\030\003 \001(\0132%.go" - + "ogle.spanner.v1.TransactionOptionsH\000B\n\n\010" - + "selector\"L\n MultiplexedSessionPrecommitT" - + "oken\022\027\n\017precommit_token\030\001 \001(\014\022\017\n\007seq_num" - + "\030\002 \001(\005B\263\001\n\025com.google.spanner.v1B\020Transa" - + "ctionProtoP\001Z5cloud.google.com/go/spanne" - + "r/apiv1/spannerpb;spannerpb\252\002\027Google.Clo" - + "ud.Spanner.V1\312\002\027Google\\Cloud\\Spanner\\V1\352" - + "\002\032Google::Cloud::Spanner::V1b\006proto3" + + "\n\037exclude_txn_from_change_streams\030\005 \001(\010\022" + + "M\n\017isolation_level\030\006 \001(\01624.google.spanne" + + "r.v1.TransactionOptions.IsolationLevel\032\354" + + "\001\n\tReadWrite\022T\n\016read_lock_mode\030\001 \001(\0162<.g" + + "oogle.spanner.v1.TransactionOptions.Read" + + "Write.ReadLockMode\0228\n+multiplexed_sessio" + + "n_previous_transaction_id\030\002 \001(\014B\003\340A\001\"O\n\014" + + "ReadLockMode\022\036\n\032READ_LOCK_MODE_UNSPECIFI" + + "ED\020\000\022\017\n\013PESSIMISTIC\020\001\022\016\n\nOPTIMISTIC\020\002\032\020\n" + + "\016PartitionedDml\032\250\002\n\010ReadOnly\022\020\n\006strong\030\001" + + " \001(\010H\000\0228\n\022min_read_timestamp\030\002 \001(\0132\032.goo" + + "gle.protobuf.TimestampH\000\0222\n\rmax_stalenes" + + "s\030\003 \001(\0132\031.google.protobuf.DurationH\000\0224\n\016" + + "read_timestamp\030\004 \001(\0132\032.google.protobuf.T" + + "imestampH\000\0224\n\017exact_staleness\030\005 \001(\0132\031.go" + + "ogle.protobuf.DurationH\000\022\035\n\025return_read_" + + "timestamp\030\006 \001(\010B\021\n\017timestamp_bound\"X\n\016Is" + + "olationLevel\022\037\n\033ISOLATION_LEVEL_UNSPECIF" + + "IED\020\000\022\020\n\014SERIALIZABLE\020\001\022\023\n\017REPEATABLE_RE" + + "AD\020\002B\006\n\004mode\"\233\001\n\013Transaction\022\n\n\002id\030\001 \001(\014" + + "\0222\n\016read_timestamp\030\002 \001(\0132\032.google.protob" + + "uf.Timestamp\022L\n\017precommit_token\030\003 \001(\01323." + + "google.spanner.v1.MultiplexedSessionPrec" + + "ommitToken\"\244\001\n\023TransactionSelector\022;\n\nsi" + + "ngle_use\030\001 \001(\0132%.google.spanner.v1.Trans" + + "actionOptionsH\000\022\014\n\002id\030\002 \001(\014H\000\0226\n\005begin\030\003" + + " \001(\0132%.google.spanner.v1.TransactionOpti" + + "onsH\000B\n\n\010selector\"L\n MultiplexedSessionP" + + "recommitToken\022\027\n\017precommit_token\030\001 \001(\014\022\017" + + "\n\007seq_num\030\002 \001(\005B\263\001\n\025com.google.spanner.v" + + "1B\020TransactionProtoP\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::V1b\006p" + + "roto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( @@ -120,7 +125,12 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_google_spanner_v1_TransactionOptions_descriptor, new java.lang.String[] { - "ReadWrite", "PartitionedDml", "ReadOnly", "ExcludeTxnFromChangeStreams", "Mode", + "ReadWrite", + "PartitionedDml", + "ReadOnly", + "ExcludeTxnFromChangeStreams", + "IsolationLevel", + "Mode", }); internal_static_google_spanner_v1_TransactionOptions_ReadWrite_descriptor = internal_static_google_spanner_v1_TransactionOptions_descriptor.getNestedTypes().get(0); diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/transaction.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/transaction.proto index fe564538466..dced12c1093 100644 --- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/transaction.proto +++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/transaction.proto @@ -361,12 +361,23 @@ message TransactionOptions { enum ReadLockMode { // Default value. // - // If the value is not specified, the pessimistic read lock is used. + // * If isolation level is `REPEATABLE_READ`, then it is an error to + // specify `read_lock_mode`. Locking semantics default to `OPTIMISTIC`. + // No validation checks are done for reads, except for: + // 1. reads done as part of queries that use `SELECT FOR UPDATE` + // 2. reads done as part of statements with a `LOCK_SCANNED_RANGES` + // hint + // 3. reads done as part of DML statements + // to validate that the data that was served at the snapshot time is + // unchanged at commit time. + // * At all other isolation levels, if `read_lock_mode` is the default + // value, then pessimistic read lock is used. READ_LOCK_MODE_UNSPECIFIED = 0; // Pessimistic lock mode. // // Read locks are acquired immediately on read. + // Semantics described only applies to `SERIALIZABLE` isolation. PESSIMISTIC = 1; // Optimistic lock mode. @@ -374,6 +385,7 @@ message TransactionOptions { // Locks for reads within the transaction are not acquired on read. // Instead the locks are acquired on a commit to validate that // read/queried data has not changed since the transaction started. + // Semantics described only applies to `SERIALIZABLE` isolation. OPTIMISTIC = 2; } @@ -461,6 +473,38 @@ message TransactionOptions { bool return_read_timestamp = 6; } + // `IsolationLevel` is used when setting `isolation_level` for a transaction. + enum IsolationLevel { + // Default value. + // + // If the value is not specified, the `SERIALIZABLE` isolation level is + // used. + ISOLATION_LEVEL_UNSPECIFIED = 0; + + // All transactions appear as if they executed in a serial order, even if + // some of the reads, writes, and other operations of distinct transactions + // actually occurred in parallel. Spanner assigns commit timestamps that + // reflect the order of committed transactions to implement this property. + // Spanner offers a stronger guarantee than serializability called external + // consistency. For further details, please refer to + // https://cloud.google.com/spanner/docs/true-time-external-consistency#serializability. + SERIALIZABLE = 1; + + // All reads performed during the transaction observe a consistent snapshot + // of the database, and the transaction will only successfully commit in the + // absence of conflicts between its updates and any concurrent updates that + // have occurred since that snapshot. Consequently, in contrast to + // `SERIALIZABLE` transactions, only write-write conflicts are detected in + // snapshot transactions. + // + // This isolation level does not support Read-only and Partitioned DML + // transactions. + // + // When `REPEATABLE_READ` is specified on a read-write transaction, the + // locking semantics default to `OPTIMISTIC`. + REPEATABLE_READ = 2; + } + // Required. The type of transaction. oneof mode { // Transaction may write. @@ -500,6 +544,9 @@ message TransactionOptions { // partitioned-dml transactions, otherwise the API will return an // `INVALID_ARGUMENT` error. bool exclude_txn_from_change_streams = 5; + + // Isolation level for the transaction. + IsolationLevel isolation_level = 6; } // A transaction. From a60f131d0c979937b4fdbd9fadd5f88f725aeec2 Mon Sep 17 00:00:00 2001 From: Sakthivel Subramanian <179120858+sakthivelmanii@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:56:26 +0530 Subject: [PATCH 02/12] ci(spanner): Fix sample tests related to asymmetric autoscaling (#3657) --- .../CreateInstanceWithAsymmetricAutoscalingConfigExample.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithAsymmetricAutoscalingConfigExample.java b/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithAsymmetricAutoscalingConfigExample.java index 421adb0f910..b4c4f8736e2 100644 --- a/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithAsymmetricAutoscalingConfigExample.java +++ b/samples/snippets/src/main/java/com/example/spanner/CreateInstanceWithAsymmetricAutoscalingConfigExample.java @@ -90,7 +90,7 @@ static void createInstance(String projectId, String instanceId) { .setInstanceId(instanceId) .setInstance(instance) .build()).get(); - System.out.printf("Autoscaler instance %s was successfully created%n", + System.out.printf("Asymmetric Autoscaling instance %s was successfully created%n", instanceResult.getName()); } catch (ExecutionException e) { System.out.printf( From 8631a24f57ae64d91f3658d1dceb699129a27ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Tue, 25 Feb 2025 17:00:28 +0100 Subject: [PATCH 03/12] test: reset unimplemented flag after test (#3659) --- ...edSessionDatabaseClientMockServerTest.java | 92 ++++++++++--------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionDatabaseClientMockServerTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionDatabaseClientMockServerTest.java index 87877caf21a..c65bab64603 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionDatabaseClientMockServerTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionDatabaseClientMockServerTest.java @@ -1569,49 +1569,55 @@ public void testInitialBeginTransactionWithRW_receivesUnimplemented_fallsBackToR // Tests the behavior of the server-side kill switch for read-write multiplexed sessions. @Test public void testPartitionedQuery_receivesUnimplemented_fallsBackToRegularSession() { - mockSpanner.setPartitionQueryExecutionTime( - SimulatedExecutionTime.ofException( - Status.INVALID_ARGUMENT - .withDescription( - "Partitioned operations are not supported with multiplexed sessions") - .asRuntimeException())); - BatchClientImpl client = (BatchClientImpl) spanner.getBatchClient(DatabaseId.of("p", "i", "d")); - - try (BatchReadOnlyTransaction transaction = - client.batchReadOnlyTransaction(TimestampBound.strong())) { - // Partitioned Query should fail - SpannerException spannerException = - assertThrows( - SpannerException.class, - () -> { - transaction.partitionQuery(PartitionOptions.getDefaultInstance(), STATEMENT); - }); - assertEquals(ErrorCode.INVALID_ARGUMENT, spannerException.getErrorCode()); - - // Verify that we received one PartitionQueryRequest. - List partitionQueryRequests = - mockSpanner.getRequestsOfType(PartitionQueryRequest.class); - assertEquals(1, partitionQueryRequests.size()); - // Verify the requests were executed using multiplexed sessions - Session session2 = mockSpanner.getSession(partitionQueryRequests.get(0).getSession()); - assertNotNull(session2); - assertTrue(session2.getMultiplexed()); - assertTrue(client.unimplementedForPartitionedOps.get()); - } - try (BatchReadOnlyTransaction transaction = - client.batchReadOnlyTransaction(TimestampBound.strong())) { - // Partitioned Query should fail - transaction.partitionQuery(PartitionOptions.getDefaultInstance(), STATEMENT); - - // // Verify that we received two PartitionQueryRequest. and it uses a regular session due to - // fallback. - List partitionQueryRequests = - mockSpanner.getRequestsOfType(PartitionQueryRequest.class); - assertEquals(2, partitionQueryRequests.size()); - // Verify the requests are not executed using multiplexed sessions - Session session2 = mockSpanner.getSession(partitionQueryRequests.get(1).getSession()); - assertNotNull(session2); - assertFalse(session2.getMultiplexed()); + try { + mockSpanner.setPartitionQueryExecutionTime( + SimulatedExecutionTime.ofException( + Status.INVALID_ARGUMENT + .withDescription( + "Partitioned operations are not supported with multiplexed sessions") + .asRuntimeException())); + BatchClientImpl client = + (BatchClientImpl) spanner.getBatchClient(DatabaseId.of("p", "i", "d")); + + try (BatchReadOnlyTransaction transaction = + client.batchReadOnlyTransaction(TimestampBound.strong())) { + // Partitioned Query should fail + SpannerException spannerException = + assertThrows( + SpannerException.class, + () -> { + transaction.partitionQuery(PartitionOptions.getDefaultInstance(), STATEMENT); + }); + assertEquals(ErrorCode.INVALID_ARGUMENT, spannerException.getErrorCode()); + + // Verify that we received one PartitionQueryRequest. + List partitionQueryRequests = + mockSpanner.getRequestsOfType(PartitionQueryRequest.class); + assertEquals(1, partitionQueryRequests.size()); + // Verify the requests were executed using multiplexed sessions + Session session2 = mockSpanner.getSession(partitionQueryRequests.get(0).getSession()); + assertNotNull(session2); + assertTrue(session2.getMultiplexed()); + assertTrue(BatchClientImpl.unimplementedForPartitionedOps.get()); + } + try (BatchReadOnlyTransaction transaction = + client.batchReadOnlyTransaction(TimestampBound.strong())) { + // Partitioned Query should fail + transaction.partitionQuery(PartitionOptions.getDefaultInstance(), STATEMENT); + + // // Verify that we received two PartitionQueryRequest. and it uses a regular session due + // to + // fallback. + List partitionQueryRequests = + mockSpanner.getRequestsOfType(PartitionQueryRequest.class); + assertEquals(2, partitionQueryRequests.size()); + // Verify the requests are not executed using multiplexed sessions + Session session2 = mockSpanner.getSession(partitionQueryRequests.get(1).getSession()); + assertNotNull(session2); + assertFalse(session2.getMultiplexed()); + } + } finally { + BatchClientImpl.unimplementedForPartitionedOps.set(false); } } From 7c714be10eb345f2d8f566d752f6de615061c4da Mon Sep 17 00:00:00 2001 From: cloud-java-bot <122572305+cloud-java-bot@users.noreply.github.com> Date: Tue, 25 Feb 2025 22:49:34 -0500 Subject: [PATCH 04/12] chore: Update generation configuration at Wed Feb 26 02:25:19 UTC 2025 (#3660) * chore: Update generation configuration at Wed Feb 26 02:25:19 UTC 2025 * chore: generate libraries at Wed Feb 26 02:25:55 UTC 2025 --- generation_config.yaml | 2 +- .../cloud/spanner/v1/SpannerClientTest.java | 2 + .../google/spanner/v1/PartialResultSet.java | 1172 ++++++++++------- .../spanner/v1/PartialResultSetOrBuilder.java | 255 ++-- .../java/com/google/spanner/v1/ResultSet.java | 375 +++--- .../google/spanner/v1/ResultSetMetadata.java | 30 +- .../v1/ResultSetMetadataOrBuilder.java | 6 +- .../google/spanner/v1/ResultSetOrBuilder.java | 87 +- .../com/google/spanner/v1/ResultSetProto.java | 40 +- .../com/google/spanner/v1/ResultSetStats.java | 54 +- .../spanner/v1/ResultSetStatsOrBuilder.java | 13 +- .../proto/google/spanner/v1/result_set.proto | 102 +- 12 files changed, 1157 insertions(+), 981 deletions(-) diff --git a/generation_config.yaml b/generation_config.yaml index a6a7866d7e2..27a5edc83af 100644 --- a/generation_config.yaml +++ b/generation_config.yaml @@ -1,5 +1,5 @@ gapic_generator_version: 2.53.0 -googleapis_commitish: 6bc8e91bf92cc985da5ed0c227b48f12315cb695 +googleapis_commitish: fbbbf5023815f9a662c85aa8af8f3b72467fcb6f libraries_bom_version: 26.55.0 libraries: - api_shortname: spanner 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 b7fc8b8d6dd..a8d7f7962a6 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 @@ -635,6 +635,7 @@ public void executeStreamingSqlTest() throws Exception { .setResumeToken(ByteString.EMPTY) .setStats(ResultSetStats.newBuilder().build()) .setPrecommitToken(MultiplexedSessionPrecommitToken.newBuilder().build()) + .setLast(true) .build(); mockSpanner.addResponse(expectedResponse); ExecuteSqlRequest request = @@ -861,6 +862,7 @@ public void streamingReadTest() throws Exception { .setResumeToken(ByteString.EMPTY) .setStats(ResultSetStats.newBuilder().build()) .setPrecommitToken(MultiplexedSessionPrecommitToken.newBuilder().build()) + .setLast(true) .build(); mockSpanner.addResponse(expectedResponse); ReadRequest request = diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSet.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSet.java index 2cdbeddbbc9..4d3387926e2 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSet.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSet.java @@ -137,13 +137,14 @@ public com.google.spanner.v1.ResultSetMetadataOrBuilder getMetadataOrBuilder() { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -154,28 +155,28 @@ public com.google.spanner.v1.ResultSetMetadataOrBuilder getMetadataOrBuilder() { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -191,7 +192,6 @@ public com.google.spanner.v1.ResultSetMetadataOrBuilder getMetadataOrBuilder() { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -201,6 +201,11 @@ public com.google.spanner.v1.ResultSetMetadataOrBuilder getMetadataOrBuilder() { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -222,13 +227,14 @@ public java.util.List getValuesList() { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -239,28 +245,28 @@ public java.util.List getValuesList() { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -276,7 +282,6 @@ public java.util.List getValuesList() { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -286,6 +291,11 @@ public java.util.List getValuesList() { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -307,13 +317,14 @@ public java.util.List getValuesOrB * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -324,28 +335,28 @@ public java.util.List getValuesOrB * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -361,7 +372,6 @@ public java.util.List getValuesOrB * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -371,6 +381,11 @@ public java.util.List getValuesOrB * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -392,13 +407,14 @@ public int getValuesCount() { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -409,28 +425,28 @@ public int getValuesCount() { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -446,7 +462,6 @@ public int getValuesCount() { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -456,6 +471,11 @@ public int getValuesCount() { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -477,13 +497,14 @@ public com.google.protobuf.Value getValues(int index) { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -494,28 +515,28 @@ public com.google.protobuf.Value getValues(int index) { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -531,7 +552,6 @@ public com.google.protobuf.Value getValues(int index) { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -541,6 +561,11 @@ public com.google.protobuf.Value getValues(int index) { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -556,9 +581,10 @@ public com.google.protobuf.ValueOrBuilder getValuesOrBuilder(int index) { * * *
-   * If true, then the final value in [values][google.spanner.v1.PartialResultSet.values] is chunked, and must
-   * be combined with more values from subsequent `PartialResultSet`s
-   * to obtain a complete field value.
+   * If true, then the final value in
+   * [values][google.spanner.v1.PartialResultSet.values] is chunked, and must be
+   * combined with more values from subsequent `PartialResultSet`s to obtain a
+   * complete field value.
    * 
* * bool chunked_value = 3; @@ -600,10 +626,9 @@ public com.google.protobuf.ByteString getResumeToken() { *
    * Query plan and execution statistics for the statement that produced this
    * streaming result set. These can be requested by setting
-   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-   * only once with the last response in the stream.
-   * This field will also be present in the last response for DML
-   * statements.
+   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+   * and are sent only once with the last response in the stream. This field is
+   * also present in the last response for DML statements.
    * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -620,10 +645,9 @@ public boolean hasStats() { *
    * Query plan and execution statistics for the statement that produced this
    * streaming result set. These can be requested by setting
-   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-   * only once with the last response in the stream.
-   * This field will also be present in the last response for DML
-   * statements.
+   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+   * and are sent only once with the last response in the stream. This field is
+   * also present in the last response for DML statements.
    * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -640,10 +664,9 @@ public com.google.spanner.v1.ResultSetStats getStats() { *
    * Query plan and execution statistics for the statement that produced this
    * streaming result set. These can be requested by setting
-   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-   * only once with the last response in the stream.
-   * This field will also be present in the last response for DML
-   * statements.
+   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+   * and are sent only once with the last response in the stream. This field is
+   * also present in the last response for DML statements.
    * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -659,13 +682,10 @@ public com.google.spanner.v1.ResultSetStatsOrBuilder getStatsOrBuilder() { * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction
+   * has multiplexed sessions enabled. Pass the precommit token with the highest
+   * sequence number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -682,13 +702,10 @@ public boolean hasPrecommitToken() { * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction
+   * has multiplexed sessions enabled. Pass the precommit token with the highest
+   * sequence number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -707,13 +724,10 @@ public com.google.spanner.v1.MultiplexedSessionPrecommitToken getPrecommitToken( * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction
+   * has multiplexed sessions enabled. Pass the precommit token with the highest
+   * sequence number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -728,6 +742,26 @@ public com.google.spanner.v1.MultiplexedSessionPrecommitToken getPrecommitToken( : precommitToken_; } + public static final int LAST_FIELD_NUMBER = 9; + private boolean last_ = false; + /** + * + * + *
+   * Optional. Indicates whether this is the last `PartialResultSet` in the
+   * stream. The server might optionally set this field. Clients shouldn't rely
+   * on this field being set in all cases.
+   * 
+ * + * bool last = 9 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The last. + */ + @java.lang.Override + public boolean getLast() { + return last_; + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -760,6 +794,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io if (((bitField0_ & 0x00000004) != 0)) { output.writeMessage(8, getPrecommitToken()); } + if (last_ != false) { + output.writeBool(9, last_); + } getUnknownFields().writeTo(output); } @@ -787,6 +824,9 @@ public int getSerializedSize() { if (((bitField0_ & 0x00000004) != 0)) { size += com.google.protobuf.CodedOutputStream.computeMessageSize(8, getPrecommitToken()); } + if (last_ != false) { + size += com.google.protobuf.CodedOutputStream.computeBoolSize(9, last_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -817,6 +857,7 @@ public boolean equals(final java.lang.Object obj) { if (hasPrecommitToken()) { if (!getPrecommitToken().equals(other.getPrecommitToken())) return false; } + if (getLast() != other.getLast()) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -848,6 +889,8 @@ public int hashCode() { hash = (37 * hash) + PRECOMMIT_TOKEN_FIELD_NUMBER; hash = (53 * hash) + getPrecommitToken().hashCode(); } + hash = (37 * hash) + LAST_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(getLast()); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -1025,6 +1068,7 @@ public Builder clear() { precommitTokenBuilder_.dispose(); precommitTokenBuilder_ = null; } + last_ = false; return this; } @@ -1094,6 +1138,9 @@ private void buildPartial0(com.google.spanner.v1.PartialResultSet result) { precommitTokenBuilder_ == null ? precommitToken_ : precommitTokenBuilder_.build(); to_bitField0_ |= 0x00000004; } + if (((from_bitField0_ & 0x00000040) != 0)) { + result.last_ = last_; + } result.bitField0_ |= to_bitField0_; } @@ -1184,6 +1231,9 @@ public Builder mergeFrom(com.google.spanner.v1.PartialResultSet other) { if (other.hasPrecommitToken()) { mergePrecommitToken(other.getPrecommitToken()); } + if (other.getLast() != false) { + setLast(other.getLast()); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -1252,6 +1302,12 @@ public Builder mergeFrom( bitField0_ |= 0x00000020; break; } // case 66 + case 72: + { + last_ = input.readBool(); + bitField0_ |= 0x00000040; + break; + } // case 72 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -1493,13 +1549,14 @@ private void ensureValuesIsMutable() { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -1510,28 +1567,28 @@ private void ensureValuesIsMutable() { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -1547,7 +1604,6 @@ private void ensureValuesIsMutable() { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -1557,6 +1613,11 @@ private void ensureValuesIsMutable() { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -1581,13 +1642,14 @@ public java.util.List getValuesList() { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -1598,28 +1660,28 @@ public java.util.List getValuesList() { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -1635,7 +1697,6 @@ public java.util.List getValuesList() { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -1645,6 +1706,11 @@ public java.util.List getValuesList() { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -1669,13 +1735,14 @@ public int getValuesCount() { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -1686,28 +1753,28 @@ public int getValuesCount() { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -1723,7 +1790,6 @@ public int getValuesCount() { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -1733,6 +1799,11 @@ public int getValuesCount() { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -1757,13 +1828,14 @@ public com.google.protobuf.Value getValues(int index) { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -1774,28 +1846,28 @@ public com.google.protobuf.Value getValues(int index) { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -1811,7 +1883,6 @@ public com.google.protobuf.Value getValues(int index) { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -1821,6 +1892,11 @@ public com.google.protobuf.Value getValues(int index) { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -1851,13 +1927,14 @@ public Builder setValues(int index, com.google.protobuf.Value value) { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -1868,28 +1945,28 @@ public Builder setValues(int index, com.google.protobuf.Value value) { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -1905,7 +1982,6 @@ public Builder setValues(int index, com.google.protobuf.Value value) { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -1915,6 +1991,11 @@ public Builder setValues(int index, com.google.protobuf.Value value) { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -1942,13 +2023,14 @@ public Builder setValues(int index, com.google.protobuf.Value.Builder builderFor * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -1959,28 +2041,28 @@ public Builder setValues(int index, com.google.protobuf.Value.Builder builderFor * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -1996,7 +2078,6 @@ public Builder setValues(int index, com.google.protobuf.Value.Builder builderFor * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2006,6 +2087,11 @@ public Builder setValues(int index, com.google.protobuf.Value.Builder builderFor * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -2036,13 +2122,14 @@ public Builder addValues(com.google.protobuf.Value value) { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -2053,28 +2140,28 @@ public Builder addValues(com.google.protobuf.Value value) { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -2090,7 +2177,6 @@ public Builder addValues(com.google.protobuf.Value value) { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2100,6 +2186,11 @@ public Builder addValues(com.google.protobuf.Value value) { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -2130,13 +2221,14 @@ public Builder addValues(int index, com.google.protobuf.Value value) { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -2147,28 +2239,28 @@ public Builder addValues(int index, com.google.protobuf.Value value) { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -2184,7 +2276,6 @@ public Builder addValues(int index, com.google.protobuf.Value value) { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2194,6 +2285,11 @@ public Builder addValues(int index, com.google.protobuf.Value value) { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -2221,13 +2317,14 @@ public Builder addValues(com.google.protobuf.Value.Builder builderForValue) { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -2238,28 +2335,28 @@ public Builder addValues(com.google.protobuf.Value.Builder builderForValue) { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -2275,7 +2372,6 @@ public Builder addValues(com.google.protobuf.Value.Builder builderForValue) { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2285,6 +2381,11 @@ public Builder addValues(com.google.protobuf.Value.Builder builderForValue) { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -2312,13 +2413,14 @@ public Builder addValues(int index, com.google.protobuf.Value.Builder builderFor * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -2329,28 +2431,28 @@ public Builder addValues(int index, com.google.protobuf.Value.Builder builderFor * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -2366,7 +2468,6 @@ public Builder addValues(int index, com.google.protobuf.Value.Builder builderFor * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2376,6 +2477,11 @@ public Builder addValues(int index, com.google.protobuf.Value.Builder builderFor * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -2403,13 +2509,14 @@ public Builder addAllValues(java.lang.Iterable * * repeated .google.protobuf.Value values = 2; @@ -2494,13 +2605,14 @@ public Builder clearValues() { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -2511,28 +2623,28 @@ public Builder clearValues() { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -2548,7 +2660,6 @@ public Builder clearValues() { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2558,6 +2669,11 @@ public Builder clearValues() { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -2585,13 +2701,14 @@ public Builder removeValues(int index) { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -2602,28 +2719,28 @@ public Builder removeValues(int index) { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -2639,7 +2756,6 @@ public Builder removeValues(int index) { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2649,6 +2765,11 @@ public Builder removeValues(int index) { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -2669,13 +2790,14 @@ public com.google.protobuf.Value.Builder getValuesBuilder(int index) { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -2686,28 +2808,28 @@ public com.google.protobuf.Value.Builder getValuesBuilder(int index) { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -2723,7 +2845,6 @@ public com.google.protobuf.Value.Builder getValuesBuilder(int index) { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2733,6 +2854,11 @@ public com.google.protobuf.Value.Builder getValuesBuilder(int index) { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -2757,13 +2883,14 @@ public com.google.protobuf.ValueOrBuilder getValuesOrBuilder(int index) { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -2774,28 +2901,28 @@ public com.google.protobuf.ValueOrBuilder getValuesOrBuilder(int index) { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -2811,7 +2938,6 @@ public com.google.protobuf.ValueOrBuilder getValuesOrBuilder(int index) { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2821,6 +2947,11 @@ public com.google.protobuf.ValueOrBuilder getValuesOrBuilder(int index) { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -2845,13 +2976,14 @@ public java.util.List getValuesOrB * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -2862,28 +2994,28 @@ public java.util.List getValuesOrB * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -2899,7 +3031,6 @@ public java.util.List getValuesOrB * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2909,6 +3040,11 @@ public java.util.List getValuesOrB * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -2929,13 +3065,14 @@ public com.google.protobuf.Value.Builder addValuesBuilder() { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -2946,28 +3083,28 @@ public com.google.protobuf.Value.Builder addValuesBuilder() { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -2983,7 +3120,6 @@ public com.google.protobuf.Value.Builder addValuesBuilder() { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -2993,6 +3129,11 @@ public com.google.protobuf.Value.Builder addValuesBuilder() { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -3014,13 +3155,14 @@ public com.google.protobuf.Value.Builder addValuesBuilder(int index) { * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -3031,28 +3173,28 @@ public com.google.protobuf.Value.Builder addValuesBuilder(int index) { * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -3068,7 +3210,6 @@ public com.google.protobuf.Value.Builder addValuesBuilder(int index) { * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -3078,6 +3219,11 @@ public com.google.protobuf.Value.Builder addValuesBuilder(int index) { * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -3108,9 +3254,10 @@ public java.util.List getValuesBuilderList() * * *
-     * If true, then the final value in [values][google.spanner.v1.PartialResultSet.values] is chunked, and must
-     * be combined with more values from subsequent `PartialResultSet`s
-     * to obtain a complete field value.
+     * If true, then the final value in
+     * [values][google.spanner.v1.PartialResultSet.values] is chunked, and must be
+     * combined with more values from subsequent `PartialResultSet`s to obtain a
+     * complete field value.
      * 
* * bool chunked_value = 3; @@ -3125,9 +3272,10 @@ public boolean getChunkedValue() { * * *
-     * If true, then the final value in [values][google.spanner.v1.PartialResultSet.values] is chunked, and must
-     * be combined with more values from subsequent `PartialResultSet`s
-     * to obtain a complete field value.
+     * If true, then the final value in
+     * [values][google.spanner.v1.PartialResultSet.values] is chunked, and must be
+     * combined with more values from subsequent `PartialResultSet`s to obtain a
+     * complete field value.
      * 
* * bool chunked_value = 3; @@ -3146,9 +3294,10 @@ public Builder setChunkedValue(boolean value) { * * *
-     * If true, then the final value in [values][google.spanner.v1.PartialResultSet.values] is chunked, and must
-     * be combined with more values from subsequent `PartialResultSet`s
-     * to obtain a complete field value.
+     * If true, then the final value in
+     * [values][google.spanner.v1.PartialResultSet.values] is chunked, and must be
+     * combined with more values from subsequent `PartialResultSet`s to obtain a
+     * complete field value.
      * 
* * bool chunked_value = 3; @@ -3241,10 +3390,9 @@ public Builder clearResumeToken() { *
      * Query plan and execution statistics for the statement that produced this
      * streaming result set. These can be requested by setting
-     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-     * only once with the last response in the stream.
-     * This field will also be present in the last response for DML
-     * statements.
+     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+     * and are sent only once with the last response in the stream. This field is
+     * also present in the last response for DML statements.
      * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -3260,10 +3408,9 @@ public boolean hasStats() { *
      * Query plan and execution statistics for the statement that produced this
      * streaming result set. These can be requested by setting
-     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-     * only once with the last response in the stream.
-     * This field will also be present in the last response for DML
-     * statements.
+     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+     * and are sent only once with the last response in the stream. This field is
+     * also present in the last response for DML statements.
      * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -3283,10 +3430,9 @@ public com.google.spanner.v1.ResultSetStats getStats() { *
      * Query plan and execution statistics for the statement that produced this
      * streaming result set. These can be requested by setting
-     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-     * only once with the last response in the stream.
-     * This field will also be present in the last response for DML
-     * statements.
+     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+     * and are sent only once with the last response in the stream. This field is
+     * also present in the last response for DML statements.
      * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -3310,10 +3456,9 @@ public Builder setStats(com.google.spanner.v1.ResultSetStats value) { *
      * Query plan and execution statistics for the statement that produced this
      * streaming result set. These can be requested by setting
-     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-     * only once with the last response in the stream.
-     * This field will also be present in the last response for DML
-     * statements.
+     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+     * and are sent only once with the last response in the stream. This field is
+     * also present in the last response for DML statements.
      * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -3334,10 +3479,9 @@ public Builder setStats(com.google.spanner.v1.ResultSetStats.Builder builderForV *
      * Query plan and execution statistics for the statement that produced this
      * streaming result set. These can be requested by setting
-     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-     * only once with the last response in the stream.
-     * This field will also be present in the last response for DML
-     * statements.
+     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+     * and are sent only once with the last response in the stream. This field is
+     * also present in the last response for DML statements.
      * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -3366,10 +3510,9 @@ public Builder mergeStats(com.google.spanner.v1.ResultSetStats value) { *
      * Query plan and execution statistics for the statement that produced this
      * streaming result set. These can be requested by setting
-     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-     * only once with the last response in the stream.
-     * This field will also be present in the last response for DML
-     * statements.
+     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+     * and are sent only once with the last response in the stream. This field is
+     * also present in the last response for DML statements.
      * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -3390,10 +3533,9 @@ public Builder clearStats() { *
      * Query plan and execution statistics for the statement that produced this
      * streaming result set. These can be requested by setting
-     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-     * only once with the last response in the stream.
-     * This field will also be present in the last response for DML
-     * statements.
+     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+     * and are sent only once with the last response in the stream. This field is
+     * also present in the last response for DML statements.
      * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -3409,10 +3551,9 @@ public com.google.spanner.v1.ResultSetStats.Builder getStatsBuilder() { *
      * Query plan and execution statistics for the statement that produced this
      * streaming result set. These can be requested by setting
-     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-     * only once with the last response in the stream.
-     * This field will also be present in the last response for DML
-     * statements.
+     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+     * and are sent only once with the last response in the stream. This field is
+     * also present in the last response for DML statements.
      * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -3430,10 +3571,9 @@ public com.google.spanner.v1.ResultSetStatsOrBuilder getStatsOrBuilder() { *
      * Query plan and execution statistics for the statement that produced this
      * streaming result set. These can be requested by setting
-     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-     * only once with the last response in the stream.
-     * This field will also be present in the last response for DML
-     * statements.
+     * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+     * and are sent only once with the last response in the stream. This field is
+     * also present in the last response for DML statements.
      * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -3465,13 +3605,10 @@ public com.google.spanner.v1.ResultSetStatsOrBuilder getStatsOrBuilder() { * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction
+     * has multiplexed sessions enabled. Pass the precommit token with the highest
+     * sequence number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -3487,13 +3624,10 @@ public boolean hasPrecommitToken() { * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction
+     * has multiplexed sessions enabled. Pass the precommit token with the highest
+     * sequence number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -3515,13 +3649,10 @@ public com.google.spanner.v1.MultiplexedSessionPrecommitToken getPrecommitToken( * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction
+     * has multiplexed sessions enabled. Pass the precommit token with the highest
+     * sequence number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -3545,13 +3676,10 @@ public Builder setPrecommitToken(com.google.spanner.v1.MultiplexedSessionPrecomm * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction
+     * has multiplexed sessions enabled. Pass the precommit token with the highest
+     * sequence number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -3573,13 +3701,10 @@ public Builder setPrecommitToken( * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction
+     * has multiplexed sessions enabled. Pass the precommit token with the highest
+     * sequence number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -3610,13 +3735,10 @@ public Builder mergePrecommitToken( * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction
+     * has multiplexed sessions enabled. Pass the precommit token with the highest
+     * sequence number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -3637,13 +3759,10 @@ public Builder clearPrecommitToken() { * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction
+     * has multiplexed sessions enabled. Pass the precommit token with the highest
+     * sequence number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -3660,13 +3779,10 @@ public Builder clearPrecommitToken() { * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction
+     * has multiplexed sessions enabled. Pass the precommit token with the highest
+     * sequence number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -3687,13 +3803,10 @@ public Builder clearPrecommitToken() { * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction
+     * has multiplexed sessions enabled. Pass the precommit token with the highest
+     * sequence number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -3717,6 +3830,65 @@ public Builder clearPrecommitToken() { return precommitTokenBuilder_; } + private boolean last_; + /** + * + * + *
+     * Optional. Indicates whether this is the last `PartialResultSet` in the
+     * stream. The server might optionally set this field. Clients shouldn't rely
+     * on this field being set in all cases.
+     * 
+ * + * bool last = 9 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The last. + */ + @java.lang.Override + public boolean getLast() { + return last_; + } + /** + * + * + *
+     * Optional. Indicates whether this is the last `PartialResultSet` in the
+     * stream. The server might optionally set this field. Clients shouldn't rely
+     * on this field being set in all cases.
+     * 
+ * + * bool last = 9 [(.google.api.field_behavior) = OPTIONAL]; + * + * @param value The last to set. + * @return This builder for chaining. + */ + public Builder setLast(boolean value) { + + last_ = value; + bitField0_ |= 0x00000040; + onChanged(); + return this; + } + /** + * + * + *
+     * Optional. Indicates whether this is the last `PartialResultSet` in the
+     * stream. The server might optionally set this field. Clients shouldn't rely
+     * on this field being set in all cases.
+     * 
+ * + * bool last = 9 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return This builder for chaining. + */ + public Builder clearLast() { + bitField0_ = (bitField0_ & ~0x00000040); + last_ = 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/PartialResultSetOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSetOrBuilder.java index 64748f45514..777addbd5ba 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSetOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/PartialResultSetOrBuilder.java @@ -75,13 +75,14 @@ public interface PartialResultSetOrBuilder * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -92,28 +93,28 @@ public interface PartialResultSetOrBuilder * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -129,7 +130,6 @@ public interface PartialResultSetOrBuilder * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -139,6 +139,11 @@ public interface PartialResultSetOrBuilder * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -157,13 +162,14 @@ public interface PartialResultSetOrBuilder * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -174,28 +180,28 @@ public interface PartialResultSetOrBuilder * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -211,7 +217,6 @@ public interface PartialResultSetOrBuilder * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -221,6 +226,11 @@ public interface PartialResultSetOrBuilder * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -239,13 +249,14 @@ public interface PartialResultSetOrBuilder * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -256,28 +267,28 @@ public interface PartialResultSetOrBuilder * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -293,7 +304,6 @@ public interface PartialResultSetOrBuilder * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -303,6 +313,11 @@ public interface PartialResultSetOrBuilder * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -321,13 +336,14 @@ public interface PartialResultSetOrBuilder * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -338,28 +354,28 @@ public interface PartialResultSetOrBuilder * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -375,7 +391,6 @@ public interface PartialResultSetOrBuilder * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -385,6 +400,11 @@ public interface PartialResultSetOrBuilder * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -403,13 +423,14 @@ public interface PartialResultSetOrBuilder * Most values are encoded based on type as described * [here][google.spanner.v1.TypeCode]. * - * It is possible that the last value in values is "chunked", + * It's possible that the last value in values is "chunked", * meaning that the rest of the value is sent in subsequent - * `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - * field. Two or more chunked values can be merged to form a - * complete value as follows: + * `PartialResultSet`(s). This is denoted by the + * [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + * Two or more chunked values can be merged to form a complete value as + * follows: * - * * `bool/number/null`: cannot be chunked + * * `bool/number/null`: can't be chunked * * `string`: concatenate the strings * * `list`: concatenate the lists. If the last element in a list is a * `string`, `list`, or `object`, merge it with the first element in @@ -420,28 +441,28 @@ public interface PartialResultSetOrBuilder * * Some examples of merging: * - * # Strings are concatenated. + * Strings are concatenated. * "foo", "bar" => "foobar" * - * # Lists of non-strings are concatenated. + * Lists of non-strings are concatenated. * [2, 3], [4] => [2, 3, 4] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are strings. * ["a", "b"], ["c", "d"] => ["a", "bc", "d"] * - * # Lists are concatenated, but the last and first elements are merged - * # because they are lists. Recursively, the last and first elements - * # of the inner lists are merged because they are strings. + * Lists are concatenated, but the last and first elements are merged + * because they are lists. Recursively, the last and first elements + * of the inner lists are merged because they are strings. * ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] * - * # Non-overlapping object fields are combined. + * Non-overlapping object fields are combined. * {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} * - * # Overlapping object fields are merged. + * Overlapping object fields are merged. * {"a": "1"}, {"a": "2"} => {"a": "12"} * - * # Examples of merging objects containing lists of strings. + * Examples of merging objects containing lists of strings. * {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} * * For a more complete example, suppose a streaming SQL query is @@ -457,7 +478,6 @@ public interface PartialResultSetOrBuilder * { * "values": ["orl"] * "chunked_value": true - * "resume_token": "Bqp2..." * } * { * "values": ["d"] @@ -467,6 +487,11 @@ public interface PartialResultSetOrBuilder * This sequence of `PartialResultSet`s encodes two rows, one * containing the field value `"Hello"`, and a second containing the * field value `"World" = "W" + "orl" + "d"`. + * + * Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + * resumed from a previously yielded `resume_token`. For the above sequence of + * `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + * yields results from the `PartialResultSet` with value "orl". * * * repeated .google.protobuf.Value values = 2; @@ -477,9 +502,10 @@ public interface PartialResultSetOrBuilder * * *
-   * If true, then the final value in [values][google.spanner.v1.PartialResultSet.values] is chunked, and must
-   * be combined with more values from subsequent `PartialResultSet`s
-   * to obtain a complete field value.
+   * If true, then the final value in
+   * [values][google.spanner.v1.PartialResultSet.values] is chunked, and must be
+   * combined with more values from subsequent `PartialResultSet`s to obtain a
+   * complete field value.
    * 
* * bool chunked_value = 3; @@ -511,10 +537,9 @@ public interface PartialResultSetOrBuilder *
    * Query plan and execution statistics for the statement that produced this
    * streaming result set. These can be requested by setting
-   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-   * only once with the last response in the stream.
-   * This field will also be present in the last response for DML
-   * statements.
+   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+   * and are sent only once with the last response in the stream. This field is
+   * also present in the last response for DML statements.
    * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -528,10 +553,9 @@ public interface PartialResultSetOrBuilder *
    * Query plan and execution statistics for the statement that produced this
    * streaming result set. These can be requested by setting
-   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-   * only once with the last response in the stream.
-   * This field will also be present in the last response for DML
-   * statements.
+   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+   * and are sent only once with the last response in the stream. This field is
+   * also present in the last response for DML statements.
    * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -545,10 +569,9 @@ public interface PartialResultSetOrBuilder *
    * Query plan and execution statistics for the statement that produced this
    * streaming result set. These can be requested by setting
-   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent
-   * only once with the last response in the stream.
-   * This field will also be present in the last response for DML
-   * statements.
+   * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]
+   * and are sent only once with the last response in the stream. This field is
+   * also present in the last response for DML statements.
    * 
* * .google.spanner.v1.ResultSetStats stats = 5; @@ -559,13 +582,10 @@ public interface PartialResultSetOrBuilder * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction
+   * has multiplexed sessions enabled. Pass the precommit token with the highest
+   * sequence number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -579,13 +599,10 @@ public interface PartialResultSetOrBuilder * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction
+   * has multiplexed sessions enabled. Pass the precommit token with the highest
+   * sequence number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -599,13 +616,10 @@ public interface PartialResultSetOrBuilder * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction
+   * has multiplexed sessions enabled. Pass the precommit token with the highest
+   * sequence number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -613,4 +627,19 @@ public interface PartialResultSetOrBuilder * */ com.google.spanner.v1.MultiplexedSessionPrecommitTokenOrBuilder getPrecommitTokenOrBuilder(); + + /** + * + * + *
+   * Optional. Indicates whether this is the last `PartialResultSet` in the
+   * stream. The server might optionally set this field. Clients shouldn't rely
+   * on this field being set in all cases.
+   * 
+ * + * bool last = 9 [(.google.api.field_behavior) = OPTIONAL]; + * + * @return The last. + */ + boolean getLast(); } diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSet.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSet.java index c5ea861bed8..82b8db2a04c 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSet.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSet.java @@ -123,11 +123,10 @@ public com.google.spanner.v1.ResultSetMetadataOrBuilder getMetadataOrBuilder() { * *
    * Each element in `rows` is a row whose format is defined by
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-   * in each row matches the ith field in
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-   * encoded based on type as described
-   * [here][google.spanner.v1.TypeCode].
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+   * element in each row matches the ith field in
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+   * are encoded based on type as described [here][google.spanner.v1.TypeCode].
    * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -141,11 +140,10 @@ public java.util.List getRowsList() { * *
    * Each element in `rows` is a row whose format is defined by
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-   * in each row matches the ith field in
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-   * encoded based on type as described
-   * [here][google.spanner.v1.TypeCode].
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+   * element in each row matches the ith field in
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+   * are encoded based on type as described [here][google.spanner.v1.TypeCode].
    * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -159,11 +157,10 @@ public java.util.List getRowsO * *
    * Each element in `rows` is a row whose format is defined by
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-   * in each row matches the ith field in
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-   * encoded based on type as described
-   * [here][google.spanner.v1.TypeCode].
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+   * element in each row matches the ith field in
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+   * are encoded based on type as described [here][google.spanner.v1.TypeCode].
    * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -177,11 +174,10 @@ public int getRowsCount() { * *
    * Each element in `rows` is a row whose format is defined by
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-   * in each row matches the ith field in
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-   * encoded based on type as described
-   * [here][google.spanner.v1.TypeCode].
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+   * element in each row matches the ith field in
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+   * are encoded based on type as described [here][google.spanner.v1.TypeCode].
    * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -195,11 +191,10 @@ public com.google.protobuf.ListValue getRows(int index) { * *
    * Each element in `rows` is a row whose format is defined by
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-   * in each row matches the ith field in
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-   * encoded based on type as described
-   * [here][google.spanner.v1.TypeCode].
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+   * element in each row matches the ith field in
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+   * are encoded based on type as described [here][google.spanner.v1.TypeCode].
    * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -220,8 +215,9 @@ public com.google.protobuf.ListValueOrBuilder getRowsOrBuilder(int index) { * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -242,8 +238,9 @@ public boolean hasStats() { * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -264,8 +261,9 @@ public com.google.spanner.v1.ResultSetStats getStats() { * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -282,13 +280,10 @@ public com.google.spanner.v1.ResultSetStatsOrBuilder getStatsOrBuilder() { * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction is on
+   * a multiplexed session. Pass the precommit token with the highest sequence
+   * number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -305,13 +300,10 @@ public boolean hasPrecommitToken() { * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction is on
+   * a multiplexed session. Pass the precommit token with the highest sequence
+   * number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -330,13 +322,10 @@ public com.google.spanner.v1.MultiplexedSessionPrecommitToken getPrecommitToken( * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction is on
+   * a multiplexed session. Pass the precommit token with the highest sequence
+   * number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -1051,11 +1040,10 @@ private void ensureRowsIsMutable() { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1072,11 +1060,10 @@ public java.util.List getRowsList() { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1093,11 +1080,10 @@ public int getRowsCount() { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1114,11 +1100,10 @@ public com.google.protobuf.ListValue getRows(int index) { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1141,11 +1126,10 @@ public Builder setRows(int index, com.google.protobuf.ListValue value) { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1165,11 +1149,10 @@ public Builder setRows(int index, com.google.protobuf.ListValue.Builder builderF * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1192,11 +1175,10 @@ public Builder addRows(com.google.protobuf.ListValue value) { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1219,11 +1201,10 @@ public Builder addRows(int index, com.google.protobuf.ListValue value) { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1243,11 +1224,10 @@ public Builder addRows(com.google.protobuf.ListValue.Builder builderForValue) { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1267,11 +1247,10 @@ public Builder addRows(int index, com.google.protobuf.ListValue.Builder builderF * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1291,11 +1270,10 @@ public Builder addAllRows(java.lang.Iterable * Each element in `rows` is a row whose format is defined by - * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element - * in each row matches the ith field in - * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are - * encoded based on type as described - * [here][google.spanner.v1.TypeCode]. + * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith + * element in each row matches the ith field in + * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements + * are encoded based on type as described [here][google.spanner.v1.TypeCode]. * * * repeated .google.protobuf.ListValue rows = 2; @@ -1315,11 +1293,10 @@ public Builder clearRows() { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1339,11 +1316,10 @@ public Builder removeRows(int index) { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1356,11 +1332,10 @@ public com.google.protobuf.ListValue.Builder getRowsBuilder(int index) { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1377,11 +1352,10 @@ public com.google.protobuf.ListValueOrBuilder getRowsOrBuilder(int index) { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1398,11 +1372,10 @@ public java.util.List getRowsO * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1415,11 +1388,10 @@ public com.google.protobuf.ListValue.Builder addRowsBuilder() { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1433,11 +1405,10 @@ public com.google.protobuf.ListValue.Builder addRowsBuilder(int index) { * *
      * Each element in `rows` is a row whose format is defined by
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-     * in each row matches the ith field in
-     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-     * encoded based on type as described
-     * [here][google.spanner.v1.TypeCode].
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+     * element in each row matches the ith field in
+     * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+     * are encoded based on type as described [here][google.spanner.v1.TypeCode].
      * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -1478,8 +1449,9 @@ public java.util.List getRowsBuilderList( * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -1499,8 +1471,9 @@ public boolean hasStats() { * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -1524,8 +1497,9 @@ public com.google.spanner.v1.ResultSetStats getStats() { * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -1553,8 +1527,9 @@ public Builder setStats(com.google.spanner.v1.ResultSetStats value) { * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -1579,8 +1554,9 @@ public Builder setStats(com.google.spanner.v1.ResultSetStats.Builder builderForV * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -1613,8 +1589,9 @@ public Builder mergeStats(com.google.spanner.v1.ResultSetStats value) { * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -1639,8 +1616,9 @@ public Builder clearStats() { * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -1660,8 +1638,9 @@ public com.google.spanner.v1.ResultSetStats.Builder getStatsBuilder() { * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -1683,8 +1662,9 @@ public com.google.spanner.v1.ResultSetStatsOrBuilder getStatsOrBuilder() { * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * * @@ -1717,13 +1697,10 @@ public com.google.spanner.v1.ResultSetStatsOrBuilder getStatsOrBuilder() { * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction is on
+     * a multiplexed session. Pass the precommit token with the highest sequence
+     * number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -1739,13 +1716,10 @@ public boolean hasPrecommitToken() { * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction is on
+     * a multiplexed session. Pass the precommit token with the highest sequence
+     * number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -1767,13 +1741,10 @@ public com.google.spanner.v1.MultiplexedSessionPrecommitToken getPrecommitToken( * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction is on
+     * a multiplexed session. Pass the precommit token with the highest sequence
+     * number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -1797,13 +1768,10 @@ public Builder setPrecommitToken(com.google.spanner.v1.MultiplexedSessionPrecomm * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction is on
+     * a multiplexed session. Pass the precommit token with the highest sequence
+     * number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -1825,13 +1793,10 @@ public Builder setPrecommitToken( * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction is on
+     * a multiplexed session. Pass the precommit token with the highest sequence
+     * number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -1862,13 +1827,10 @@ public Builder mergePrecommitToken( * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction is on
+     * a multiplexed session. Pass the precommit token with the highest sequence
+     * number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -1889,13 +1851,10 @@ public Builder clearPrecommitToken() { * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction is on
+     * a multiplexed session. Pass the precommit token with the highest sequence
+     * number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -1912,13 +1871,10 @@ public Builder clearPrecommitToken() { * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction is on
+     * a multiplexed session. Pass the precommit token with the highest sequence
+     * number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * @@ -1939,13 +1895,10 @@ public Builder clearPrecommitToken() { * * *
-     * Optional. A precommit token will be included if the read-write transaction
-     * is on a multiplexed session.
-     * The precommit token with the highest sequence number from this transaction
-     * attempt should be passed to the
+     * Optional. A precommit token is included if the read-write transaction is on
+     * a multiplexed session. Pass the precommit token with the highest sequence
+     * number from this transaction attempt to the
      * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-     * This feature is not yet supported and will result in an UNIMPLEMENTED
-     * error.
      * 
* * diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadata.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadata.java index 39be68d3aaf..bc6e8652737 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadata.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadata.java @@ -23,7 +23,8 @@ * * *
- * Metadata about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet].
+ * Metadata about a [ResultSet][google.spanner.v1.ResultSet] or
+ * [PartialResultSet][google.spanner.v1.PartialResultSet].
  * 
* * Protobuf type {@code google.spanner.v1.ResultSetMetadata} @@ -69,7 +70,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { * *
    * Indicates the field names and types for the rows in the result
-   * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+   * set. For example, a SQL query like `"SELECT UserId, UserName FROM
    * Users"` could return a `row_type` value like:
    *
    *     "fields": [
@@ -91,7 +92,7 @@ public boolean hasRowType() {
    *
    * 
    * Indicates the field names and types for the rows in the result
-   * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+   * set. For example, a SQL query like `"SELECT UserId, UserName FROM
    * Users"` could return a `row_type` value like:
    *
    *     "fields": [
@@ -113,7 +114,7 @@ public com.google.spanner.v1.StructType getRowType() {
    *
    * 
    * Indicates the field names and types for the rows in the result
-   * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+   * set. For example, a SQL query like `"SELECT UserId, UserName FROM
    * Users"` could return a `row_type` value like:
    *
    *     "fields": [
@@ -455,7 +456,8 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build
    *
    *
    * 
-   * Metadata about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet].
+   * Metadata about a [ResultSet][google.spanner.v1.ResultSet] or
+   * [PartialResultSet][google.spanner.v1.PartialResultSet].
    * 
* * Protobuf type {@code google.spanner.v1.ResultSetMetadata} @@ -701,7 +703,7 @@ public Builder mergeFrom( * *
      * Indicates the field names and types for the rows in the result
-     * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+     * set. For example, a SQL query like `"SELECT UserId, UserName FROM
      * Users"` could return a `row_type` value like:
      *
      *     "fields": [
@@ -722,7 +724,7 @@ public boolean hasRowType() {
      *
      * 
      * Indicates the field names and types for the rows in the result
-     * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+     * set. For example, a SQL query like `"SELECT UserId, UserName FROM
      * Users"` could return a `row_type` value like:
      *
      *     "fields": [
@@ -747,7 +749,7 @@ public com.google.spanner.v1.StructType getRowType() {
      *
      * 
      * Indicates the field names and types for the rows in the result
-     * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+     * set. For example, a SQL query like `"SELECT UserId, UserName FROM
      * Users"` could return a `row_type` value like:
      *
      *     "fields": [
@@ -776,7 +778,7 @@ public Builder setRowType(com.google.spanner.v1.StructType value) {
      *
      * 
      * Indicates the field names and types for the rows in the result
-     * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+     * set. For example, a SQL query like `"SELECT UserId, UserName FROM
      * Users"` could return a `row_type` value like:
      *
      *     "fields": [
@@ -802,7 +804,7 @@ public Builder setRowType(com.google.spanner.v1.StructType.Builder builderForVal
      *
      * 
      * Indicates the field names and types for the rows in the result
-     * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+     * set. For example, a SQL query like `"SELECT UserId, UserName FROM
      * Users"` could return a `row_type` value like:
      *
      *     "fields": [
@@ -836,7 +838,7 @@ public Builder mergeRowType(com.google.spanner.v1.StructType value) {
      *
      * 
      * Indicates the field names and types for the rows in the result
-     * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+     * set. For example, a SQL query like `"SELECT UserId, UserName FROM
      * Users"` could return a `row_type` value like:
      *
      *     "fields": [
@@ -862,7 +864,7 @@ public Builder clearRowType() {
      *
      * 
      * Indicates the field names and types for the rows in the result
-     * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+     * set. For example, a SQL query like `"SELECT UserId, UserName FROM
      * Users"` could return a `row_type` value like:
      *
      *     "fields": [
@@ -883,7 +885,7 @@ public com.google.spanner.v1.StructType.Builder getRowTypeBuilder() {
      *
      * 
      * Indicates the field names and types for the rows in the result
-     * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+     * set. For example, a SQL query like `"SELECT UserId, UserName FROM
      * Users"` could return a `row_type` value like:
      *
      *     "fields": [
@@ -906,7 +908,7 @@ public com.google.spanner.v1.StructTypeOrBuilder getRowTypeOrBuilder() {
      *
      * 
      * Indicates the field names and types for the rows in the result
-     * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+     * set. For example, a SQL query like `"SELECT UserId, UserName FROM
      * Users"` could return a `row_type` value like:
      *
      *     "fields": [
diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadataOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadataOrBuilder.java
index 3598bd0405f..38ab303ed36 100644
--- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadataOrBuilder.java
+++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetMetadataOrBuilder.java
@@ -29,7 +29,7 @@ public interface ResultSetMetadataOrBuilder
    *
    * 
    * Indicates the field names and types for the rows in the result
-   * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+   * set. For example, a SQL query like `"SELECT UserId, UserName FROM
    * Users"` could return a `row_type` value like:
    *
    *     "fields": [
@@ -48,7 +48,7 @@ public interface ResultSetMetadataOrBuilder
    *
    * 
    * Indicates the field names and types for the rows in the result
-   * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+   * set. For example, a SQL query like `"SELECT UserId, UserName FROM
    * Users"` could return a `row_type` value like:
    *
    *     "fields": [
@@ -67,7 +67,7 @@ public interface ResultSetMetadataOrBuilder
    *
    * 
    * Indicates the field names and types for the rows in the result
-   * set.  For example, a SQL query like `"SELECT UserId, UserName FROM
+   * set. For example, a SQL query like `"SELECT UserId, UserName FROM
    * Users"` could return a `row_type` value like:
    *
    *     "fields": [
diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetOrBuilder.java
index 5debcb0ddd8..85e38392255 100644
--- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetOrBuilder.java
+++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetOrBuilder.java
@@ -64,11 +64,10 @@ public interface ResultSetOrBuilder
    *
    * 
    * Each element in `rows` is a row whose format is defined by
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-   * in each row matches the ith field in
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-   * encoded based on type as described
-   * [here][google.spanner.v1.TypeCode].
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+   * element in each row matches the ith field in
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+   * are encoded based on type as described [here][google.spanner.v1.TypeCode].
    * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -79,11 +78,10 @@ public interface ResultSetOrBuilder * *
    * Each element in `rows` is a row whose format is defined by
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-   * in each row matches the ith field in
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-   * encoded based on type as described
-   * [here][google.spanner.v1.TypeCode].
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+   * element in each row matches the ith field in
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+   * are encoded based on type as described [here][google.spanner.v1.TypeCode].
    * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -94,11 +92,10 @@ public interface ResultSetOrBuilder * *
    * Each element in `rows` is a row whose format is defined by
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-   * in each row matches the ith field in
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-   * encoded based on type as described
-   * [here][google.spanner.v1.TypeCode].
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+   * element in each row matches the ith field in
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+   * are encoded based on type as described [here][google.spanner.v1.TypeCode].
    * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -109,11 +106,10 @@ public interface ResultSetOrBuilder * *
    * Each element in `rows` is a row whose format is defined by
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-   * in each row matches the ith field in
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-   * encoded based on type as described
-   * [here][google.spanner.v1.TypeCode].
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+   * element in each row matches the ith field in
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+   * are encoded based on type as described [here][google.spanner.v1.TypeCode].
    * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -124,11 +120,10 @@ public interface ResultSetOrBuilder * *
    * Each element in `rows` is a row whose format is defined by
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element
-   * in each row matches the ith field in
-   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are
-   * encoded based on type as described
-   * [here][google.spanner.v1.TypeCode].
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith
+   * element in each row matches the ith field in
+   * [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements
+   * are encoded based on type as described [here][google.spanner.v1.TypeCode].
    * 
* * repeated .google.protobuf.ListValue rows = 2; @@ -144,8 +139,9 @@ public interface ResultSetOrBuilder * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. *
* @@ -163,8 +159,9 @@ public interface ResultSetOrBuilder * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. *
* @@ -182,8 +179,9 @@ public interface ResultSetOrBuilder * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. * DML statements always produce stats containing the number of rows * modified, unless executed using the - * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - * Other fields may or may not be populated, based on the + * [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + * Other fields might or might not be populated, based on the * [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. *
* @@ -195,13 +193,10 @@ public interface ResultSetOrBuilder * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction is on
+   * a multiplexed session. Pass the precommit token with the highest sequence
+   * number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -215,13 +210,10 @@ public interface ResultSetOrBuilder * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction is on
+   * a multiplexed session. Pass the precommit token with the highest sequence
+   * number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * @@ -235,13 +227,10 @@ public interface ResultSetOrBuilder * * *
-   * Optional. A precommit token will be included if the read-write transaction
-   * is on a multiplexed session.
-   * The precommit token with the highest sequence number from this transaction
-   * attempt should be passed to the
+   * Optional. A precommit token is included if the read-write transaction is on
+   * a multiplexed session. Pass the precommit token with the highest sequence
+   * number from this transaction attempt to the
    * [Commit][google.spanner.v1.Spanner.Commit] request for this transaction.
-   * This feature is not yet supported and will result in an UNIMPLEMENTED
-   * error.
    * 
* * diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java index 84beab76ecd..899e7b0a27a 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetProto.java @@ -64,7 +64,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "buf.ListValue\0220\n\005stats\030\003 \001(\0132!.google.sp" + "anner.v1.ResultSetStats\022Q\n\017precommit_tok" + "en\030\005 \001(\01323.google.spanner.v1.Multiplexed" - + "SessionPrecommitTokenB\003\340A\001\"\244\002\n\020PartialRe" + + "SessionPrecommitTokenB\003\340A\001\"\267\002\n\020PartialRe" + "sultSet\0226\n\010metadata\030\001 \001(\0132$.google.spann" + "er.v1.ResultSetMetadata\022&\n\006values\030\002 \003(\0132" + "\026.google.protobuf.Value\022\025\n\rchunked_value" @@ -72,21 +72,21 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "\001(\0132!.google.spanner.v1.ResultSetStats\022Q" + "\n\017precommit_token\030\010 \001(\01323.google.spanner" + ".v1.MultiplexedSessionPrecommitTokenB\003\340A" - + "\001\"\267\001\n\021ResultSetMetadata\022/\n\010row_type\030\001 \001(" - + "\0132\035.google.spanner.v1.StructType\0223\n\013tran" - + "saction\030\002 \001(\0132\036.google.spanner.v1.Transa" - + "ction\022<\n\025undeclared_parameters\030\003 \001(\0132\035.g" - + "oogle.spanner.v1.StructType\"\271\001\n\016ResultSe" - + "tStats\0220\n\nquery_plan\030\001 \001(\0132\034.google.span" - + "ner.v1.QueryPlan\022,\n\013query_stats\030\002 \001(\0132\027." - + "google.protobuf.Struct\022\031\n\017row_count_exac" - + "t\030\003 \001(\003H\000\022\037\n\025row_count_lower_bound\030\004 \001(\003" - + "H\000B\013\n\trow_countB\264\001\n\025com.google.spanner.v" - + "1B\016ResultSetProtoP\001Z5cloud.google.com/go" - + "/spanner/apiv1/spannerpb;spannerpb\370\001\001\252\002\027" - + "Google.Cloud.Spanner.V1\312\002\027Google\\Cloud\\S" - + "panner\\V1\352\002\032Google::Cloud::Spanner::V1b\006" - + "proto3" + + "\001\022\021\n\004last\030\t \001(\010B\003\340A\001\"\267\001\n\021ResultSetMetada" + + "ta\022/\n\010row_type\030\001 \001(\0132\035.google.spanner.v1" + + ".StructType\0223\n\013transaction\030\002 \001(\0132\036.googl" + + "e.spanner.v1.Transaction\022<\n\025undeclared_p" + + "arameters\030\003 \001(\0132\035.google.spanner.v1.Stru" + + "ctType\"\271\001\n\016ResultSetStats\0220\n\nquery_plan\030" + + "\001 \001(\0132\034.google.spanner.v1.QueryPlan\022,\n\013q" + + "uery_stats\030\002 \001(\0132\027.google.protobuf.Struc" + + "t\022\031\n\017row_count_exact\030\003 \001(\003H\000\022\037\n\025row_coun" + + "t_lower_bound\030\004 \001(\003H\000B\013\n\trow_countB\261\001\n\025c" + + "om.google.spanner.v1B\016ResultSetProtoP\001Z5" + + "cloud.google.com/go/spanner/apiv1/spanne" + + "rpb;spannerpb\252\002\027Google.Cloud.Spanner.V1\312" + + "\002\027Google\\Cloud\\Spanner\\V1\352\002\032Google::Clou" + + "d::Spanner::V1b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( @@ -112,7 +112,13 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_google_spanner_v1_PartialResultSet_descriptor, new java.lang.String[] { - "Metadata", "Values", "ChunkedValue", "ResumeToken", "Stats", "PrecommitToken", + "Metadata", + "Values", + "ChunkedValue", + "ResumeToken", + "Stats", + "PrecommitToken", + "Last", }); internal_static_google_spanner_v1_ResultSetMetadata_descriptor = getDescriptor().getMessageTypes().get(2); diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStats.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStats.java index b13da2d2282..1ed3c04f33a 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStats.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStats.java @@ -23,7 +23,8 @@ * * *
- * Additional statistics about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet].
+ * Additional statistics about a [ResultSet][google.spanner.v1.ResultSet] or
+ * [PartialResultSet][google.spanner.v1.PartialResultSet].
  * 
* * Protobuf type {@code google.spanner.v1.ResultSetStats} @@ -117,7 +118,8 @@ public RowCountCase getRowCountCase() { * * *
-   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+   * result.
    * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -132,7 +134,8 @@ public boolean hasQueryPlan() { * * *
-   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+   * result.
    * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -147,7 +150,8 @@ public com.google.spanner.v1.QueryPlan getQueryPlan() { * * *
-   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+   * result.
    * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -267,7 +271,7 @@ public long getRowCountExact() { * * *
-   * Partitioned DML does not offer exactly-once semantics, so it
+   * Partitioned DML doesn't offer exactly-once semantics, so it
    * returns a lower bound of the rows modified.
    * 
* @@ -283,7 +287,7 @@ public boolean hasRowCountLowerBound() { * * *
-   * Partitioned DML does not offer exactly-once semantics, so it
+   * Partitioned DML doesn't offer exactly-once semantics, so it
    * returns a lower bound of the rows modified.
    * 
* @@ -518,7 +522,8 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build * * *
-   * Additional statistics about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet].
+   * Additional statistics about a [ResultSet][google.spanner.v1.ResultSet] or
+   * [PartialResultSet][google.spanner.v1.PartialResultSet].
    * 
* * Protobuf type {@code google.spanner.v1.ResultSetStats} @@ -788,7 +793,8 @@ public Builder clearRowCount() { * * *
-     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+     * result.
      * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -802,7 +808,8 @@ public boolean hasQueryPlan() { * * *
-     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+     * result.
      * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -822,7 +829,8 @@ public com.google.spanner.v1.QueryPlan getQueryPlan() { * * *
-     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+     * result.
      * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -844,7 +852,8 @@ public Builder setQueryPlan(com.google.spanner.v1.QueryPlan value) { * * *
-     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+     * result.
      * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -863,7 +872,8 @@ public Builder setQueryPlan(com.google.spanner.v1.QueryPlan.Builder builderForVa * * *
-     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+     * result.
      * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -890,7 +900,8 @@ public Builder mergeQueryPlan(com.google.spanner.v1.QueryPlan value) { * * *
-     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+     * result.
      * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -909,7 +920,8 @@ public Builder clearQueryPlan() { * * *
-     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+     * result.
      * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -923,7 +935,8 @@ public com.google.spanner.v1.QueryPlan.Builder getQueryPlanBuilder() { * * *
-     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+     * result.
      * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -941,7 +954,8 @@ public com.google.spanner.v1.QueryPlanOrBuilder getQueryPlanOrBuilder() { * * *
-     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+     * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+     * result.
      * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -1290,7 +1304,7 @@ public Builder clearRowCountExact() { * * *
-     * Partitioned DML does not offer exactly-once semantics, so it
+     * Partitioned DML doesn't offer exactly-once semantics, so it
      * returns a lower bound of the rows modified.
      * 
* @@ -1305,7 +1319,7 @@ public boolean hasRowCountLowerBound() { * * *
-     * Partitioned DML does not offer exactly-once semantics, so it
+     * Partitioned DML doesn't offer exactly-once semantics, so it
      * returns a lower bound of the rows modified.
      * 
* @@ -1323,7 +1337,7 @@ public long getRowCountLowerBound() { * * *
-     * Partitioned DML does not offer exactly-once semantics, so it
+     * Partitioned DML doesn't offer exactly-once semantics, so it
      * returns a lower bound of the rows modified.
      * 
* @@ -1343,7 +1357,7 @@ public Builder setRowCountLowerBound(long value) { * * *
-     * Partitioned DML does not offer exactly-once semantics, so it
+     * Partitioned DML doesn't offer exactly-once semantics, so it
      * returns a lower bound of the rows modified.
      * 
* diff --git a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStatsOrBuilder.java b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStatsOrBuilder.java index a3fd01bb7ab..343981c2d87 100644 --- a/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStatsOrBuilder.java +++ b/proto-google-cloud-spanner-v1/src/main/java/com/google/spanner/v1/ResultSetStatsOrBuilder.java @@ -28,7 +28,8 @@ public interface ResultSetStatsOrBuilder * * *
-   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+   * result.
    * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -40,7 +41,8 @@ public interface ResultSetStatsOrBuilder * * *
-   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+   * result.
    * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -52,7 +54,8 @@ public interface ResultSetStatsOrBuilder * * *
-   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result.
+   * [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this
+   * result.
    * 
* * .google.spanner.v1.QueryPlan query_plan = 1; @@ -147,7 +150,7 @@ public interface ResultSetStatsOrBuilder * * *
-   * Partitioned DML does not offer exactly-once semantics, so it
+   * Partitioned DML doesn't offer exactly-once semantics, so it
    * returns a lower bound of the rows modified.
    * 
* @@ -160,7 +163,7 @@ public interface ResultSetStatsOrBuilder * * *
-   * Partitioned DML does not offer exactly-once semantics, so it
+   * Partitioned DML doesn't offer exactly-once semantics, so it
    * returns a lower bound of the rows modified.
    * 
* diff --git a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/result_set.proto b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/result_set.proto index 0b8aabf8679..3735eeddc16 100644 --- a/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/result_set.proto +++ b/proto-google-cloud-spanner-v1/src/main/proto/google/spanner/v1/result_set.proto @@ -22,7 +22,6 @@ import "google/spanner/v1/query_plan.proto"; import "google/spanner/v1/transaction.proto"; import "google/spanner/v1/type.proto"; -option cc_enable_arenas = true; option csharp_namespace = "Google.Cloud.Spanner.V1"; option go_package = "cloud.google.com/go/spanner/apiv1/spannerpb;spannerpb"; option java_multiple_files = true; @@ -38,11 +37,10 @@ message ResultSet { ResultSetMetadata metadata = 1; // Each element in `rows` is a row whose format is defined by - // [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element - // in each row matches the ith field in - // [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are - // encoded based on type as described - // [here][google.spanner.v1.TypeCode]. + // [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith + // element in each row matches the ith field in + // [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements + // are encoded based on type as described [here][google.spanner.v1.TypeCode]. repeated google.protobuf.ListValue rows = 2; // Query plan and execution statistics for the SQL statement that @@ -50,18 +48,16 @@ message ResultSet { // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. // DML statements always produce stats containing the number of rows // modified, unless executed using the - // [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. - // Other fields may or may not be populated, based on the + // [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] + // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + // Other fields might or might not be populated, based on the // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. ResultSetStats stats = 3; - // Optional. A precommit token will be included if the read-write transaction - // is on a multiplexed session. - // The precommit token with the highest sequence number from this transaction - // attempt should be passed to the + // Optional. A precommit token is included if the read-write transaction is on + // a multiplexed session. Pass the precommit token with the highest sequence + // number from this transaction attempt to the // [Commit][google.spanner.v1.Spanner.Commit] request for this transaction. - // This feature is not yet supported and will result in an UNIMPLEMENTED - // error. MultiplexedSessionPrecommitToken precommit_token = 5 [(google.api.field_behavior) = OPTIONAL]; } @@ -83,13 +79,14 @@ message PartialResultSet { // Most values are encoded based on type as described // [here][google.spanner.v1.TypeCode]. // - // It is possible that the last value in values is "chunked", + // It's possible that the last value in values is "chunked", // meaning that the rest of the value is sent in subsequent - // `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] - // field. Two or more chunked values can be merged to form a - // complete value as follows: + // `PartialResultSet`(s). This is denoted by the + // [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] field. + // Two or more chunked values can be merged to form a complete value as + // follows: // - // * `bool/number/null`: cannot be chunked + // * `bool/number/null`: can't be chunked // * `string`: concatenate the strings // * `list`: concatenate the lists. If the last element in a list is a // `string`, `list`, or `object`, merge it with the first element in @@ -100,28 +97,28 @@ message PartialResultSet { // // Some examples of merging: // - // # Strings are concatenated. + // Strings are concatenated. // "foo", "bar" => "foobar" // - // # Lists of non-strings are concatenated. + // Lists of non-strings are concatenated. // [2, 3], [4] => [2, 3, 4] // - // # Lists are concatenated, but the last and first elements are merged - // # because they are strings. + // Lists are concatenated, but the last and first elements are merged + // because they are strings. // ["a", "b"], ["c", "d"] => ["a", "bc", "d"] // - // # Lists are concatenated, but the last and first elements are merged - // # because they are lists. Recursively, the last and first elements - // # of the inner lists are merged because they are strings. + // Lists are concatenated, but the last and first elements are merged + // because they are lists. Recursively, the last and first elements + // of the inner lists are merged because they are strings. // ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] // - // # Non-overlapping object fields are combined. + // Non-overlapping object fields are combined. // {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} // - // # Overlapping object fields are merged. + // Overlapping object fields are merged. // {"a": "1"}, {"a": "2"} => {"a": "12"} // - // # Examples of merging objects containing lists of strings. + // Examples of merging objects containing lists of strings. // {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} // // For a more complete example, suppose a streaming SQL query is @@ -137,7 +134,6 @@ message PartialResultSet { // { // "values": ["orl"] // "chunked_value": true - // "resume_token": "Bqp2..." // } // { // "values": ["d"] @@ -147,11 +143,17 @@ message PartialResultSet { // This sequence of `PartialResultSet`s encodes two rows, one // containing the field value `"Hello"`, and a second containing the // field value `"World" = "W" + "orl" + "d"`. + // + // Not all `PartialResultSet`s contain a `resume_token`. Execution can only be + // resumed from a previously yielded `resume_token`. For the above sequence of + // `PartialResultSet`s, resuming the query with `"resume_token": "Af65..."` + // yields results from the `PartialResultSet` with value "orl". repeated google.protobuf.Value values = 2; - // If true, then the final value in [values][google.spanner.v1.PartialResultSet.values] is chunked, and must - // be combined with more values from subsequent `PartialResultSet`s - // to obtain a complete field value. + // If true, then the final value in + // [values][google.spanner.v1.PartialResultSet.values] is chunked, and must be + // combined with more values from subsequent `PartialResultSet`s to obtain a + // complete field value. bool chunked_value = 3; // Streaming calls might be interrupted for a variety of reasons, such @@ -163,27 +165,29 @@ message PartialResultSet { // Query plan and execution statistics for the statement that produced this // streaming result set. These can be requested by setting - // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent - // only once with the last response in the stream. - // This field will also be present in the last response for DML - // statements. + // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] + // and are sent only once with the last response in the stream. This field is + // also present in the last response for DML statements. ResultSetStats stats = 5; - // Optional. A precommit token will be included if the read-write transaction - // is on a multiplexed session. - // The precommit token with the highest sequence number from this transaction - // attempt should be passed to the + // Optional. A precommit token is included if the read-write transaction + // has multiplexed sessions enabled. Pass the precommit token with the highest + // sequence number from this transaction attempt to the // [Commit][google.spanner.v1.Spanner.Commit] request for this transaction. - // This feature is not yet supported and will result in an UNIMPLEMENTED - // error. MultiplexedSessionPrecommitToken precommit_token = 8 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. Indicates whether this is the last `PartialResultSet` in the + // stream. The server might optionally set this field. Clients shouldn't rely + // on this field being set in all cases. + bool last = 9 [(google.api.field_behavior) = OPTIONAL]; } -// Metadata about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet]. +// Metadata about a [ResultSet][google.spanner.v1.ResultSet] or +// [PartialResultSet][google.spanner.v1.PartialResultSet]. message ResultSetMetadata { // Indicates the field names and types for the rows in the result - // set. For example, a SQL query like `"SELECT UserId, UserName FROM + // set. For example, a SQL query like `"SELECT UserId, UserName FROM // Users"` could return a `row_type` value like: // // "fields": [ @@ -209,9 +213,11 @@ message ResultSetMetadata { StructType undeclared_parameters = 3; } -// Additional statistics about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet]. +// Additional statistics about a [ResultSet][google.spanner.v1.ResultSet] or +// [PartialResultSet][google.spanner.v1.PartialResultSet]. message ResultSetStats { - // [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result. + // [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this + // result. QueryPlan query_plan = 1; // Aggregated statistics from the execution of the query. Only present when @@ -230,7 +236,7 @@ message ResultSetStats { // Standard DML returns an exact count of rows that were modified. int64 row_count_exact = 3; - // Partitioned DML does not offer exactly-once semantics, so it + // Partitioned DML doesn't offer exactly-once semantics, so it // returns a lower bound of the rows modified. int64 row_count_lower_bound = 4; } From b86c0bb260192a79b752af5fc55c42ec6fd03692 Mon Sep 17 00:00:00 2001 From: Sakthivel Subramanian <179120858+sakthivelmanii@users.noreply.github.com> Date: Wed, 26 Feb 2025 11:38:33 +0530 Subject: [PATCH 05/12] chore(spanner): Update codeowner team to Teamsync managed team (#3662) --- .github/CODEOWNERS | 2 +- .repo-metadata.json | 2 +- generation_config.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 701064032d1..af827785424 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,5 +4,5 @@ # For syntax help see: # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax -# The @googleapis/api-spanner-java is the default owner for changes in this repo +# The @googleapis/spanner-client-libraries-java is the default owner for changes in this repo * @googleapis/yoshi-java @googleapis/spanner-client-libraries-java diff --git a/.repo-metadata.json b/.repo-metadata.json index 670b37d595a..03835744989 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -13,7 +13,7 @@ "api_id": "spanner.googleapis.com", "library_type": "GAPIC_COMBO", "requires_billing": true, - "codeowner_team": "@googleapis/api-spanner-java", + "codeowner_team": "@googleapis/spanner-client-libraries-java", "excluded_poms": "google-cloud-spanner-bom", "issue_tracker": "https://issuetracker.google.com/issues?q=componentid:190851%2B%20status:open", "recommended_package": "com.google.cloud.spanner", diff --git a/generation_config.yaml b/generation_config.yaml index 27a5edc83af..0c02ec882aa 100644 --- a/generation_config.yaml +++ b/generation_config.yaml @@ -17,7 +17,7 @@ libraries: api_id: spanner.googleapis.com transport: grpc requires_billing: true - codeowner_team: '@googleapis/api-spanner-java' + codeowner_team: '@googleapis/spanner-client-libraries-java' library_type: GAPIC_COMBO excluded_poms: google-cloud-spanner-bom recommended_package: com.google.cloud.spanner From ace11d5d928fb567b16560263ae95aa9cd916e22 Mon Sep 17 00:00:00 2001 From: Sagnik Ghosh Date: Wed, 26 Feb 2025 14:01:58 +0530 Subject: [PATCH 06/12] feat: default authentication support for external hosts (#3656) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: default authentication support for external hosts * unit test added * unit test typo * skip auth_token in emulator host for jdbc * skip auth_token for emulator * env variable prefix change * code refactor to handle edge cases * chore: create util method for reading token from file * chore: fix clirr failure * test: reset unimplemented flag after test --------- Co-authored-by: Knut Olav Løite --- .../clirr-ignored-differences.xml | 6 +++ .../google/cloud/spanner/SpannerOptions.java | 48 +++++++++++++++++++ .../spanner/connection/ConnectionOptions.java | 4 ++ .../cloud/spanner/SpannerOptionsTest.java | 9 ++++ 4 files changed, 67 insertions(+) diff --git a/google-cloud-spanner/clirr-ignored-differences.xml b/google-cloud-spanner/clirr-ignored-differences.xml index c6796085d83..4e03926c66e 100644 --- a/google-cloud-spanner/clirr-ignored-differences.xml +++ b/google-cloud-spanner/clirr-ignored-differences.xml @@ -822,4 +822,10 @@ java.lang.Object runTransaction(com.google.cloud.spanner.connection.Connection$TransactionCallable) + + + 7012 + com/google/cloud/spanner/SpannerOptions$SpannerEnvironment + com.google.auth.oauth2.GoogleCredentials getDefaultExternalHostCredentials() + diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java index 5b63ff4fe44..43978a1d04c 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java @@ -34,6 +34,8 @@ import com.google.api.gax.tracing.ApiTracerFactory; import com.google.api.gax.tracing.BaseApiTracerFactory; import com.google.api.gax.tracing.OpencensusTracerFactory; +import com.google.auth.oauth2.AccessToken; +import com.google.auth.oauth2.GoogleCredentials; import com.google.cloud.NoCredentials; import com.google.cloud.ServiceDefaults; import com.google.cloud.ServiceOptions; @@ -56,6 +58,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.ThreadFactoryBuilder; @@ -79,8 +82,11 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; import java.time.Duration; import java.util.ArrayList; +import java.util.Base64; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -92,6 +98,7 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Pattern; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; @@ -110,6 +117,11 @@ public class SpannerOptions extends ServiceOptions { private static final String API_SHORT_NAME = "Spanner"; private static final String DEFAULT_HOST = "https://spanner.googleapis.com"; + private static final String CLOUD_SPANNER_HOST_FORMAT = ".*\\.googleapis\\.com.*"; + + @VisibleForTesting + static final Pattern CLOUD_SPANNER_HOST_PATTERN = Pattern.compile(CLOUD_SPANNER_HOST_FORMAT); + private static final ImmutableSet SCOPES = ImmutableSet.of( "https://www.googleapis.com/auth/spanner.admin", @@ -843,8 +855,15 @@ default boolean isEnableEndToEndTracing() { default String getMonitoringHost() { return null; } + + default GoogleCredentials getDefaultExternalHostCredentials() { + return null; + } } + static final String DEFAULT_SPANNER_EXTERNAL_HOST_CREDENTIALS = + "SPANNER_EXTERNAL_HOST_AUTH_TOKEN"; + /** * Default implementation of {@link SpannerEnvironment}. Reads all configuration from environment * variables. @@ -900,6 +919,11 @@ public boolean isEnableEndToEndTracing() { public String getMonitoringHost() { return System.getenv(SPANNER_MONITORING_HOST); } + + @Override + public GoogleCredentials getDefaultExternalHostCredentials() { + return getOAuthTokenFromFile(System.getenv(DEFAULT_SPANNER_EXTERNAL_HOST_CREDENTIALS)); + } } /** Builder for {@link SpannerOptions} instances. */ @@ -967,6 +991,7 @@ public static class Builder private boolean enableBuiltInMetrics = SpannerOptions.environment.isEnableBuiltInMetrics(); private String monitoringHost = SpannerOptions.environment.getMonitoringHost(); private SslContext mTLSContext = null; + private boolean isExternalHost = false; private static String createCustomClientLibToken(String token) { return token + " " + ServiceOptions.getGoogApiClientLibName(); @@ -1459,6 +1484,9 @@ public Builder setDecodeMode(DecodeMode decodeMode) { @Override public Builder setHost(String host) { super.setHost(host); + if (!CLOUD_SPANNER_HOST_PATTERN.matcher(host).matches()) { + this.isExternalHost = true; + } // Setting a host should override any SPANNER_EMULATOR_HOST setting. setEmulatorHost(null); return this; @@ -1629,6 +1657,8 @@ public SpannerOptions build() { this.setChannelConfigurator(ManagedChannelBuilder::usePlaintext); // As we are using plain text, we should never send any credentials. this.setCredentials(NoCredentials.getInstance()); + } else if (isExternalHost && credentials == null) { + credentials = environment.getDefaultExternalHostCredentials(); } if (this.numChannels == null) { this.numChannels = @@ -1669,6 +1699,24 @@ public static void useDefaultEnvironment() { SpannerOptions.environment = SpannerEnvironmentImpl.INSTANCE; } + @InternalApi + public static GoogleCredentials getDefaultExternalHostCredentialsFromSysEnv() { + return getOAuthTokenFromFile(System.getenv(DEFAULT_SPANNER_EXTERNAL_HOST_CREDENTIALS)); + } + + private static @Nullable GoogleCredentials getOAuthTokenFromFile(@Nullable String file) { + if (!Strings.isNullOrEmpty(file)) { + String token; + try { + token = Base64.getEncoder().encodeToString(Files.readAllBytes(Paths.get(file))); + } catch (IOException e) { + throw SpannerExceptionFactory.newSpannerException(e); + } + return GoogleCredentials.create(new AccessToken(token, null)); + } + return null; + } + /** * Enables OpenTelemetry traces. Enabling OpenTelemetry traces will disable OpenCensus traces. By * default, OpenCensus traces are enabled. diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java index d205699bb9e..deb279d8e3e 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java @@ -921,6 +921,8 @@ private ConnectionOptions(Builder builder) { getInitialConnectionPropertyValue(AUTO_CONFIG_EMULATOR), usePlainText, System.getenv()); + GoogleCredentials defaultExternalHostCredentials = + SpannerOptions.getDefaultExternalHostCredentialsFromSysEnv(); // Using credentials on a plain text connection is not allowed, so if the user has not specified // any credentials and is using a plain text connection, we should not try to get the // credentials from the environment, but default to NoCredentials. @@ -935,6 +937,8 @@ && getInitialConnectionPropertyValue(OAUTH_TOKEN) == null this.credentials = new GoogleCredentials( new AccessToken(getInitialConnectionPropertyValue(OAUTH_TOKEN), null)); + } else if (isExternalHost && defaultExternalHostCredentials != null) { + this.credentials = defaultExternalHostCredentials; } else if (getInitialConnectionPropertyValue(CREDENTIALS_PROVIDER) != null) { try { this.credentials = getInitialConnectionPropertyValue(CREDENTIALS_PROVIDER).getCredentials(); diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java index 70482c0ffdd..72bbdf82eae 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerOptionsTest.java @@ -16,6 +16,7 @@ package com.google.cloud.spanner; +import static com.google.cloud.spanner.SpannerOptions.CLOUD_SPANNER_HOST_PATTERN; import static com.google.common.truth.Truth.assertThat; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -1164,4 +1165,12 @@ public void checkGlobalOpenTelemetryWhenNotInjected() { .build(); assertEquals(GlobalOpenTelemetry.get(), options.getOpenTelemetry()); } + + @Test + public void testCloudSpannerHostPattern() { + assertTrue(CLOUD_SPANNER_HOST_PATTERN.matcher("https://spanner.googleapis.com").matches()); + assertTrue( + CLOUD_SPANNER_HOST_PATTERN.matcher("https://product-area.googleapis.com:443").matches()); + assertFalse(CLOUD_SPANNER_HOST_PATTERN.matcher("https://some-company.com:443").matches()); + } } From 8d1423fb2c7bd44fa5a386c98b3e12473b967420 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 20:17:03 +0530 Subject: [PATCH 07/12] chore(main): release 6.87.1-SNAPSHOT (#3653) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- benchmarks/pom.xml | 2 +- google-cloud-spanner-bom/pom.xml | 18 ++++++++--------- google-cloud-spanner-executor/pom.xml | 4 ++-- google-cloud-spanner/pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- grpc-google-cloud-spanner-executor-v1/pom.xml | 4 ++-- grpc-google-cloud-spanner-v1/pom.xml | 4 ++-- pom.xml | 20 +++++++++---------- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- proto-google-cloud-spanner-v1/pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 20 +++++++++---------- 15 files changed, 51 insertions(+), 51 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 255b64175bf..5dc655d72c7 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -24,7 +24,7 @@ com.google.cloud google-cloud-spanner-parent - 6.87.0 + 6.87.1-SNAPSHOT diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index 3e3df860023..5bfc2df28f4 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.87.0 + 6.87.1-SNAPSHOT pom com.google.cloud @@ -53,43 +53,43 @@ com.google.cloud google-cloud-spanner - 6.87.0 + 6.87.1-SNAPSHOT com.google.cloud google-cloud-spanner test-jar - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.87.0 + 6.87.1-SNAPSHOT diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index ded694843c2..118993fff25 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.87.0 + 6.87.1-SNAPSHOT jar Google Cloud Spanner Executor com.google.cloud google-cloud-spanner-parent - 6.87.0 + 6.87.1-SNAPSHOT diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 9f7aadb8a15..5b0e11894f6 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.87.0 + 6.87.1-SNAPSHOT jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.87.0 + 6.87.1-SNAPSHOT google-cloud-spanner diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index 1ceb1073b98..ffded2f717f 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.87.0 + 6.87.1-SNAPSHOT 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.87.0 + 6.87.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index 3be48a22c4c..82bbf6a83c8 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.87.0 + 6.87.1-SNAPSHOT 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.87.0 + 6.87.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-executor-v1/pom.xml b/grpc-google-cloud-spanner-executor-v1/pom.xml index a1950b288ec..2601c52ae1f 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.87.0 + 6.87.1-SNAPSHOT grpc-google-cloud-spanner-executor-v1 GRPC library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.87.0 + 6.87.1-SNAPSHOT diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index eb81ef2cd5a..d2fc10186b8 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.87.0 + 6.87.1-SNAPSHOT grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.87.0 + 6.87.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 41909b12055..5c3e2d561b0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.87.0 + 6.87.1-SNAPSHOT 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.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.87.0 + 6.87.1-SNAPSHOT com.google.cloud google-cloud-spanner - 6.87.0 + 6.87.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index 59979f00a92..a8877ec4993 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.87.0 + 6.87.1-SNAPSHOT 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.87.0 + 6.87.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index 1c8d7b9c0a9..2aabd553523 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.87.0 + 6.87.1-SNAPSHOT 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.87.0 + 6.87.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-executor-v1/pom.xml b/proto-google-cloud-spanner-executor-v1/pom.xml index 31dd6136825..3420c2b4079 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.87.0 + 6.87.1-SNAPSHOT proto-google-cloud-spanner-executor-v1 Proto library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.87.0 + 6.87.1-SNAPSHOT diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index fbe27a10d50..f92985f9730 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.87.0 + 6.87.1-SNAPSHOT proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.87.0 + 6.87.1-SNAPSHOT diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 4140f77781c..ea087ed0255 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -32,7 +32,7 @@ com.google.cloud google-cloud-spanner - 6.87.0 + 6.87.1-SNAPSHOT diff --git a/versions.txt b/versions.txt index de3c4756dd0..8ab160eb598 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.87.0:6.87.0 -proto-google-cloud-spanner-v1:6.87.0:6.87.0 -proto-google-cloud-spanner-admin-database-v1:6.87.0:6.87.0 -grpc-google-cloud-spanner-v1:6.87.0:6.87.0 -grpc-google-cloud-spanner-admin-instance-v1:6.87.0:6.87.0 -grpc-google-cloud-spanner-admin-database-v1:6.87.0:6.87.0 -google-cloud-spanner:6.87.0:6.87.0 -google-cloud-spanner-executor:6.87.0:6.87.0 -proto-google-cloud-spanner-executor-v1:6.87.0:6.87.0 -grpc-google-cloud-spanner-executor-v1:6.87.0:6.87.0 +proto-google-cloud-spanner-admin-instance-v1:6.87.0:6.87.1-SNAPSHOT +proto-google-cloud-spanner-v1:6.87.0:6.87.1-SNAPSHOT +proto-google-cloud-spanner-admin-database-v1:6.87.0:6.87.1-SNAPSHOT +grpc-google-cloud-spanner-v1:6.87.0:6.87.1-SNAPSHOT +grpc-google-cloud-spanner-admin-instance-v1:6.87.0:6.87.1-SNAPSHOT +grpc-google-cloud-spanner-admin-database-v1:6.87.0:6.87.1-SNAPSHOT +google-cloud-spanner:6.87.0:6.87.1-SNAPSHOT +google-cloud-spanner-executor:6.87.0:6.87.1-SNAPSHOT +proto-google-cloud-spanner-executor-v1:6.87.0:6.87.1-SNAPSHOT +grpc-google-cloud-spanner-executor-v1:6.87.0:6.87.1-SNAPSHOT From e8abf338b85e95f185ab2875a804134523f84de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Thu, 27 Feb 2025 09:02:59 +0100 Subject: [PATCH 08/12] feat: automatically set default sequence kind in JDBC and PGAdapter (#3658) * feat: automatically set default sequence kind in JDBC and PGAdapter Add a connection property that automatically sets the default sequence kind for a database if a DDL statement fails due to no default sequence kind having been set. This allows tools like PGAdapter and ORMs that use JDBC to automatically use auto_increment columns without the need to add an ALTER DATABASE statement. * chore: fix clirr failures * test: fix integration test * fix: correctly retry if a failure happens in the middle --- .../clirr-ignored-differences.xml | 12 ++ .../MissingDefaultSequenceKindException.java | 52 ++++++ .../spanner/SpannerExceptionFactory.java | 4 + .../cloud/spanner/connection/Connection.java | 12 ++ .../spanner/connection/ConnectionImpl.java | 18 ++- .../spanner/connection/ConnectionOptions.java | 2 + .../connection/ConnectionProperties.java | 25 +-- .../cloud/spanner/connection/DdlBatch.java | 31 +++- .../cloud/spanner/connection/DdlClient.java | 47 ++++++ .../connection/SingleUseTransaction.java | 123 +++++++------- .../spanner/connection/DdlBatchTest.java | 24 ++- .../cloud/spanner/connection/DdlTest.java | 130 +++++++++++++++ .../connection/SingleUseTransactionTest.java | 26 ++- .../spanner/connection/it/ITDdlTest.java | 152 ++++++++++++++++++ 14 files changed, 563 insertions(+), 95 deletions(-) create mode 100644 google-cloud-spanner/src/main/java/com/google/cloud/spanner/MissingDefaultSequenceKindException.java diff --git a/google-cloud-spanner/clirr-ignored-differences.xml b/google-cloud-spanner/clirr-ignored-differences.xml index 4e03926c66e..5c103beca6f 100644 --- a/google-cloud-spanner/clirr-ignored-differences.xml +++ b/google-cloud-spanner/clirr-ignored-differences.xml @@ -828,4 +828,16 @@ com/google/cloud/spanner/SpannerOptions$SpannerEnvironment com.google.auth.oauth2.GoogleCredentials getDefaultExternalHostCredentials() + + + + 7012 + com/google/cloud/spanner/connection/Connection + void setDefaultSequenceKind(java.lang.String) + + + 7012 + com/google/cloud/spanner/connection/Connection + java.lang.String getDefaultSequenceKind() + diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/MissingDefaultSequenceKindException.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/MissingDefaultSequenceKindException.java new file mode 100644 index 00000000000..7b61dbbd881 --- /dev/null +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/MissingDefaultSequenceKindException.java @@ -0,0 +1,52 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner; + +import com.google.api.gax.rpc.ApiException; +import java.util.regex.Pattern; +import javax.annotation.Nullable; + +/** + * Exception thrown by Spanner when a DDL statement failed because no default sequence kind has been + * configured for a database. + */ +public class MissingDefaultSequenceKindException extends SpannerException { + private static final long serialVersionUID = 1L; + + private static final Pattern PATTERN = + Pattern.compile( + "The sequence kind of an identity column .+ is not specified\\. Please specify the sequence kind explicitly or set the database option `default_sequence_kind`\\."); + + /** Private constructor. Use {@link SpannerExceptionFactory} to create instances. */ + MissingDefaultSequenceKindException( + DoNotConstructDirectly token, + ErrorCode errorCode, + String message, + Throwable cause, + @Nullable ApiException apiException) { + super(token, errorCode, /*retryable = */ false, message, cause, apiException); + } + + static boolean isMissingDefaultSequenceKindException(Throwable cause) { + if (cause == null + || cause.getMessage() == null + || !PATTERN.matcher(cause.getMessage()).find()) { + return false; + } + return true; + } +} 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 a3f174cda60..6476b94b144 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,6 +16,7 @@ package com.google.cloud.spanner; +import static com.google.cloud.spanner.MissingDefaultSequenceKindException.isMissingDefaultSequenceKindException; import static com.google.cloud.spanner.TransactionMutationLimitExceededException.isTransactionMutationLimitException; import com.google.api.gax.grpc.GrpcStatusCode; @@ -336,6 +337,9 @@ static SpannerException newSpannerExceptionPreformatted( return new TransactionMutationLimitExceededException( token, code, message, cause, apiException); } + if (isMissingDefaultSequenceKindException(apiException)) { + return new MissingDefaultSequenceKindException(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/connection/Connection.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/Connection.java index eb69ae132cc..7bf4e47bd9a 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/Connection.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/Connection.java @@ -862,6 +862,18 @@ interface TransactionCallable { /** Sets how the connection should behave if a DDL statement is executed during a transaction. */ void setDdlInTransactionMode(DdlInTransactionMode ddlInTransactionMode); + /** + * Returns the default sequence kind that will be set for this database if a DDL statement is + * executed that uses auto_increment or serial. + */ + String getDefaultSequenceKind(); + + /** + * Sets the default sequence kind that will be set for this database if a DDL statement is + * executed that uses auto_increment or serial. + */ + void setDefaultSequenceKind(String defaultSequenceKind); + /** * Creates a savepoint with the given name. * 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 5ea249ee0ac..4c0c95a91a5 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 @@ -27,6 +27,7 @@ import static com.google.cloud.spanner.connection.ConnectionProperties.AUTO_PARTITION_MODE; import static com.google.cloud.spanner.connection.ConnectionProperties.DATA_BOOST_ENABLED; import static com.google.cloud.spanner.connection.ConnectionProperties.DDL_IN_TRANSACTION_MODE; +import static com.google.cloud.spanner.connection.ConnectionProperties.DEFAULT_SEQUENCE_KIND; import static com.google.cloud.spanner.connection.ConnectionProperties.DELAY_TRANSACTION_START_UNTIL_FIRST_WRITE; import static com.google.cloud.spanner.connection.ConnectionProperties.DIRECTED_READ; import static com.google.cloud.spanner.connection.ConnectionProperties.KEEP_TRANSACTION_ALIVE; @@ -761,6 +762,16 @@ public void setDdlInTransactionMode(DdlInTransactionMode ddlInTransactionMode) { setConnectionPropertyValue(DDL_IN_TRANSACTION_MODE, ddlInTransactionMode); } + @Override + public String getDefaultSequenceKind() { + return getConnectionPropertyValue(DEFAULT_SEQUENCE_KIND); + } + + @Override + public void setDefaultSequenceKind(String defaultSequenceKind) { + setConnectionPropertyValue(DEFAULT_SEQUENCE_KIND, defaultSequenceKind); + } + @Override public void setStatementTimeout(long timeout, TimeUnit unit) { Preconditions.checkArgument(timeout > 0L, "Zero or negative timeout values are not allowed"); @@ -2152,13 +2163,9 @@ UnitOfWork createNewUnitOfWork( .setDdlClient(ddlClient) .setDatabaseClient(dbClient) .setBatchClient(batchClient) - .setReadOnly(getConnectionPropertyValue(READONLY)) - .setReadOnlyStaleness(getConnectionPropertyValue(READ_ONLY_STALENESS)) - .setAutocommitDmlMode(getConnectionPropertyValue(AUTOCOMMIT_DML_MODE)) + .setConnectionState(connectionState) .setTransactionRetryListeners(transactionRetryListeners) - .setReturnCommitStats(getConnectionPropertyValue(RETURN_COMMIT_STATS)) .setExcludeTxnFromChangeStreams(excludeTxnFromChangeStreams) - .setMaxCommitDelay(getConnectionPropertyValue(MAX_COMMIT_DELAY)) .setStatementTimeout(statementTimeout) .withStatementExecutor(statementExecutor) .setSpan( @@ -2230,6 +2237,7 @@ UnitOfWork createNewUnitOfWork( .withStatementExecutor(statementExecutor) .setSpan(createSpanForUnitOfWork(DDL_BATCH)) .setProtoDescriptors(getProtoDescriptors()) + .setConnectionState(connectionState) .build(); default: } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java index deb279d8e3e..f63d8f1f10c 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java @@ -242,6 +242,7 @@ public String[] getValidValues() { static final RpcPriority DEFAULT_RPC_PRIORITY = null; static final DdlInTransactionMode DEFAULT_DDL_IN_TRANSACTION_MODE = DdlInTransactionMode.ALLOW_IN_EMPTY_TRANSACTION; + static final String DEFAULT_DEFAULT_SEQUENCE_KIND = null; static final boolean DEFAULT_RETURN_COMMIT_STATS = false; static final boolean DEFAULT_LENIENT = false; static final boolean DEFAULT_ROUTE_TO_LEADER = true; @@ -324,6 +325,7 @@ public String[] getValidValues() { public static final String RPC_PRIORITY_NAME = "rpcPriority"; public static final String DDL_IN_TRANSACTION_MODE_PROPERTY_NAME = "ddlInTransactionMode"; + public static final String DEFAULT_SEQUENCE_KIND_PROPERTY_NAME = "defaultSequenceKind"; /** Dialect to use for a connection. */ static final String DIALECT_PROPERTY_NAME = "dialect"; /** Name of the 'databaseRole' connection property. */ diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java index 6f2628e5a04..f65dc533570 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java @@ -41,6 +41,7 @@ import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_DATABASE_ROLE; import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_DATA_BOOST_ENABLED; import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_DDL_IN_TRANSACTION_MODE; +import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_DEFAULT_SEQUENCE_KIND; import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_DELAY_TRANSACTION_START_UNTIL_FIRST_WRITE; import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_ENABLE_API_TRACING; import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_ENABLE_END_TO_END_TRACING; @@ -61,6 +62,7 @@ import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_RETURN_COMMIT_STATS; import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_ROUTE_TO_LEADER; import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_RPC_PRIORITY; +import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_SEQUENCE_KIND_PROPERTY_NAME; import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_TRACK_CONNECTION_LEAKS; import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_TRACK_SESSION_LEAKS; import static com.google.cloud.spanner.connection.ConnectionOptions.DEFAULT_USER_AGENT; @@ -531,6 +533,15 @@ public class ConnectionProperties { DdlInTransactionMode.values(), DdlInTransactionModeConverter.INSTANCE, Context.USER); + static final ConnectionProperty DEFAULT_SEQUENCE_KIND = + create( + DEFAULT_SEQUENCE_KIND_PROPERTY_NAME, + "The default sequence kind that should be used for the database. " + + "This property is only used when a DDL statement that requires a default " + + "sequence kind is executed on this connection.", + DEFAULT_DEFAULT_SEQUENCE_KIND, + StringValueConverter.INSTANCE, + Context.USER); static final ConnectionProperty MAX_COMMIT_DELAY = create( "maxCommitDelay", @@ -615,16 +626,10 @@ private static ConnectionProperty create( T[] validValues, ClientSideStatementValueConverter converter, Context context) { - try { - ConnectionProperty property = - ConnectionProperty.create( - name, description, defaultValue, validValues, converter, context); - CONNECTION_PROPERTIES_BUILDER.put(property.getKey(), property); - return property; - } catch (Throwable t) { - t.printStackTrace(); - } - return null; + ConnectionProperty property = + ConnectionProperty.create(name, description, defaultValue, validValues, converter, context); + CONNECTION_PROPERTIES_BUILDER.put(property.getKey(), property); + return property; } /** Parse the connection properties that can be found in the given connection URL. */ diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlBatch.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlBatch.java index 6ae28822473..813f5d6e45b 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlBatch.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlBatch.java @@ -17,6 +17,7 @@ package com.google.cloud.spanner.connection; import static com.google.cloud.spanner.connection.AbstractStatementParser.RUN_BATCH_STATEMENT; +import static com.google.cloud.spanner.connection.ConnectionProperties.DEFAULT_SEQUENCE_KIND; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; @@ -45,6 +46,7 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nonnull; /** @@ -61,11 +63,13 @@ class DdlBatch extends AbstractBaseUnitOfWork { private final List statements = new ArrayList<>(); private UnitOfWorkState state = UnitOfWorkState.STARTED; private final byte[] protoDescriptors; + private final ConnectionState connectionState; static class Builder extends AbstractBaseUnitOfWork.Builder { private DdlClient ddlClient; private DatabaseClient dbClient; private byte[] protoDescriptors; + private ConnectionState connectionState; private Builder() {} @@ -86,6 +90,11 @@ Builder setProtoDescriptors(byte[] protoDescriptors) { return this; } + Builder setConnectionState(ConnectionState connectionState) { + this.connectionState = connectionState; + return this; + } + @Override DdlBatch build() { Preconditions.checkState(ddlClient != null, "No DdlClient specified"); @@ -103,6 +112,7 @@ private DdlBatch(Builder builder) { this.ddlClient = builder.ddlClient; this.dbClient = builder.dbClient; this.protoDescriptors = builder.protoDescriptors; + this.connectionState = Preconditions.checkNotNull(builder.connectionState); } @Override @@ -235,17 +245,28 @@ public ApiFuture runBatchAsync(CallType callType) { Callable callable = () -> { try { - OperationFuture operation = - ddlClient.executeDdl(statements, protoDescriptors); + AtomicReference> operationReference = + new AtomicReference<>(); try { - // Wait until the operation has finished. - getWithStatementTimeout(operation, RUN_BATCH_STATEMENT); + ddlClient.runWithRetryForMissingDefaultSequenceKind( + restartIndex -> { + OperationFuture operation = + ddlClient.executeDdl( + statements.subList(restartIndex, statements.size()), + protoDescriptors); + operationReference.set(operation); + // Wait until the operation has finished. + getWithStatementTimeout(operation, RUN_BATCH_STATEMENT); + }, + connectionState.getValue(DEFAULT_SEQUENCE_KIND).getValue(), + dbClient.getDialect(), + operationReference); long[] updateCounts = new long[statements.size()]; Arrays.fill(updateCounts, 1L); state = UnitOfWorkState.RAN; return updateCounts; } catch (SpannerException e) { - long[] updateCounts = extractUpdateCounts(operation); + long[] updateCounts = extractUpdateCounts(operationReference.get()); throw SpannerExceptionFactory.newSpannerBatchUpdateException( e.getErrorCode(), e.getMessage(), updateCounts); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlClient.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlClient.java index 7bce1ab78cd..a3dc286acb4 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlClient.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/DdlClient.java @@ -22,6 +22,8 @@ import com.google.cloud.spanner.DatabaseId; import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ErrorCode; +import com.google.cloud.spanner.MissingDefaultSequenceKindException; +import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.SpannerExceptionFactory; import com.google.common.base.Preconditions; import com.google.common.base.Strings; @@ -29,6 +31,9 @@ import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import java.util.Collections; import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; /** * Convenience class for executing Data Definition Language statements on transactions that support @@ -131,4 +136,46 @@ static boolean isCreateDatabaseStatement(String statement) { && tokens[0].equalsIgnoreCase("CREATE") && tokens[1].equalsIgnoreCase("DATABASE"); } + + void runWithRetryForMissingDefaultSequenceKind( + Consumer runnable, + String defaultSequenceKind, + Dialect dialect, + AtomicReference> operationReference) { + try { + runnable.accept(0); + } catch (Throwable t) { + SpannerException spannerException = SpannerExceptionFactory.asSpannerException(t); + if (!Strings.isNullOrEmpty(defaultSequenceKind) + && spannerException instanceof MissingDefaultSequenceKindException) { + setDefaultSequenceKind(defaultSequenceKind, dialect); + int restartIndex = 0; + if (operationReference.get() != null) { + try { + UpdateDatabaseDdlMetadata metadata = operationReference.get().getMetadata().get(); + restartIndex = metadata.getCommitTimestampsCount(); + } catch (Throwable ignore) { + } + } + runnable.accept(restartIndex); + return; + } + throw t; + } + } + + private void setDefaultSequenceKind(String defaultSequenceKind, Dialect dialect) { + String ddl = + dialect == Dialect.POSTGRESQL + ? "alter database \"%s\" set spanner.default_sequence_kind = '%s'" + : "alter database `%s` set options (default_sequence_kind='%s')"; + ddl = String.format(ddl, databaseName, defaultSequenceKind); + try { + executeDdl(ddl, null).get(); + } catch (ExecutionException executionException) { + throw SpannerExceptionFactory.asSpannerException(executionException.getCause()); + } catch (InterruptedException interruptedException) { + throw SpannerExceptionFactory.propagateInterrupt(interruptedException); + } + } } 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 a827f82ba36..8a5cd6a26db 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 @@ -18,6 +18,13 @@ import static com.google.cloud.spanner.connection.AbstractStatementParser.COMMIT_STATEMENT; import static com.google.cloud.spanner.connection.AbstractStatementParser.RUN_BATCH_STATEMENT; +import static com.google.cloud.spanner.connection.ConnectionProperties.AUTOCOMMIT_DML_MODE; +import static com.google.cloud.spanner.connection.ConnectionProperties.DEFAULT_SEQUENCE_KIND; +import static com.google.cloud.spanner.connection.ConnectionProperties.MAX_COMMIT_DELAY; +import static com.google.cloud.spanner.connection.ConnectionProperties.READONLY; +import static com.google.cloud.spanner.connection.ConnectionProperties.READ_ONLY_STALENESS; +import static com.google.cloud.spanner.connection.ConnectionProperties.RETURN_COMMIT_STATS; +import static com.google.cloud.spanner.connection.DdlClient.isCreateDatabaseStatement; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutureCallback; @@ -43,7 +50,6 @@ import com.google.cloud.spanner.SpannerBatchUpdateException; 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.connection.AbstractStatementParser.ParsedStatement; @@ -55,10 +61,10 @@ import com.google.spanner.admin.database.v1.DatabaseAdminGrpc; import com.google.spanner.v1.SpannerGrpc; import io.opentelemetry.context.Scope; -import java.time.Duration; import java.util.Arrays; import java.util.UUID; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nonnull; /** @@ -78,15 +84,11 @@ * */ class SingleUseTransaction extends AbstractBaseUnitOfWork { - private final boolean readOnly; private final DdlClient ddlClient; private final DatabaseClient dbClient; private final BatchClient batchClient; - private final TimestampBound readOnlyStaleness; - private final AutocommitDmlMode autocommitDmlMode; - private final boolean returnCommitStats; - private final Duration maxCommitDelay; - private final boolean internalMetdataQuery; + private final ConnectionState connectionState; + private final boolean internalMetadataQuery; private final byte[] protoDescriptors; private volatile SettableApiFuture readTimestamp = null; private volatile TransactionRunner writeTransaction; @@ -97,11 +99,7 @@ static class Builder extends AbstractBaseUnitOfWork.Builder executeQueryAsync( // Do not use a read-only staleness for internal metadata queries. final ReadOnlyTransaction currentTransaction = - internalMetdataQuery + internalMetadataQuery ? dbClient.singleUseReadOnlyTransaction() - : dbClient.singleUseReadOnlyTransaction(readOnlyStaleness); + : dbClient.singleUseReadOnlyTransaction( + connectionState.getValue(READ_ONLY_STALENESS).getValue()); Callable callable = () -> { try { @@ -325,7 +300,8 @@ public ApiFuture partitionQueryAsync( Callable callable = () -> { try (BatchReadOnlyTransaction transaction = - batchClient.batchReadOnlyTransaction(readOnlyStaleness)) { + batchClient.batchReadOnlyTransaction( + connectionState.getValue(READ_ONLY_STALENESS).getValue())) { ResultSet resultSet = partitionQuery(transaction, partitionOptions, query, options); readTimestamp.set(transaction.getReadTimestamp()); state = UnitOfWorkState.COMMITTED; @@ -408,15 +384,19 @@ public ApiFuture executeDdlAsync(CallType callType, final ParsedStatement Callable callable = () -> { try { - OperationFuture operation; - if (DdlClient.isCreateDatabaseStatement(ddl.getSqlWithoutComments())) { - operation = - ddlClient.executeCreateDatabase( - ddl.getSqlWithoutComments(), dbClient.getDialect()); + if (isCreateDatabaseStatement(ddl.getSqlWithoutComments())) { + executeCreateDatabase(ddl); } else { - operation = ddlClient.executeDdl(ddl.getSqlWithoutComments(), protoDescriptors); + ddlClient.runWithRetryForMissingDefaultSequenceKind( + restartIndex -> { + OperationFuture operation = + ddlClient.executeDdl(ddl.getSqlWithoutComments(), protoDescriptors); + getWithStatementTimeout(operation, ddl); + }, + connectionState.getValue(DEFAULT_SEQUENCE_KIND).getValue(), + dbClient.getDialect(), + new AtomicReference<>()); } - getWithStatementTimeout(operation, ddl); state = UnitOfWorkState.COMMITTED; return null; } catch (Throwable t) { @@ -429,6 +409,12 @@ public ApiFuture executeDdlAsync(CallType callType, final ParsedStatement } } + private void executeCreateDatabase(ParsedStatement ddl) { + OperationFuture operation = + ddlClient.executeCreateDatabase(ddl.getSqlWithoutComments(), dbClient.getDialect()); + getWithStatementTimeout(operation, ddl); + } + @Override public ApiFuture executeUpdateAsync( CallType callType, ParsedStatement update, UpdateOption... options) { @@ -440,7 +426,7 @@ public ApiFuture executeUpdateAsync( checkAndMarkUsed(); ApiFuture res; - switch (autocommitDmlMode) { + switch (getAutocommitDmlMode()) { case TRANSACTIONAL: case TRANSACTIONAL_WITH_FALLBACK_TO_PARTITIONED_NON_ATOMIC: res = @@ -454,7 +440,7 @@ public ApiFuture executeUpdateAsync( break; default: throw SpannerExceptionFactory.newSpannerException( - ErrorCode.FAILED_PRECONDITION, "Unknown dml mode: " + autocommitDmlMode); + ErrorCode.FAILED_PRECONDITION, "Unknown dml mode: " + getAutocommitDmlMode()); } return res; } @@ -468,7 +454,7 @@ public ApiFuture analyzeUpdateAsync( ConnectionPreconditions.checkState( !isReadOnly(), "Update statements are not allowed in read-only mode"); ConnectionPreconditions.checkState( - autocommitDmlMode != AutocommitDmlMode.PARTITIONED_NON_ATOMIC, + getAutocommitDmlMode() != AutocommitDmlMode.PARTITIONED_NON_ATOMIC, "Analyzing update statements is not supported for Partitioned DML"); try (Scope ignore = span.makeCurrent()) { checkAndMarkUsed(); @@ -494,16 +480,16 @@ public ApiFuture executeBatchUpdateAsync( try (Scope ignore = span.makeCurrent()) { checkAndMarkUsed(); - switch (autocommitDmlMode) { + switch (getAutocommitDmlMode()) { case TRANSACTIONAL: return executeTransactionalBatchUpdateAsync(callType, updates, options); case PARTITIONED_NON_ATOMIC: throw SpannerExceptionFactory.newSpannerException( ErrorCode.FAILED_PRECONDITION, - "Batch updates are not allowed in " + autocommitDmlMode); + "Batch updates are not allowed in " + getAutocommitDmlMode()); default: throw SpannerExceptionFactory.newSpannerException( - ErrorCode.FAILED_PRECONDITION, "Unknown dml mode: " + autocommitDmlMode); + ErrorCode.FAILED_PRECONDITION, "Unknown dml mode: " + getAutocommitDmlMode()); } } } @@ -513,13 +499,13 @@ private TransactionRunner createWriteTransaction() { if (this.rpcPriority != null) { numOptions++; } - if (returnCommitStats) { + if (connectionState.getValue(RETURN_COMMIT_STATS).getValue()) { numOptions++; } if (excludeTxnFromChangeStreams) { numOptions++; } - if (maxCommitDelay != null) { + if (connectionState.getValue(MAX_COMMIT_DELAY).getValue() != null) { numOptions++; } if (numOptions == 0) { @@ -530,14 +516,15 @@ private TransactionRunner createWriteTransaction() { if (this.rpcPriority != null) { options[index++] = Options.priority(this.rpcPriority); } - if (returnCommitStats) { + if (connectionState.getValue(RETURN_COMMIT_STATS).getValue()) { options[index++] = Options.commitStats(); } if (excludeTxnFromChangeStreams) { options[index++] = Options.excludeTxnFromChangeStreams(); } - if (maxCommitDelay != null) { - options[index++] = Options.maxCommitDelay(maxCommitDelay); + if (connectionState.getValue(MAX_COMMIT_DELAY).getValue() != null) { + options[index++] = + Options.maxCommitDelay(connectionState.getValue(MAX_COMMIT_DELAY).getValue()); } return dbClient.readWriteTransaction(options); } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java index 93ae60891fb..4d582e09007 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlBatchTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.anyList; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -59,6 +60,7 @@ import java.io.InputStream; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; @@ -115,6 +117,9 @@ private DdlClient createDefaultMockDdlClient( when(operation.getMetadata()).thenReturn(metadataFuture); when(ddlClient.executeDdl(anyString(), any())).thenReturn(operation); when(ddlClient.executeDdl(anyList(), any())).thenReturn(operation); + doCallRealMethod() + .when(ddlClient) + .runWithRetryForMissingDefaultSequenceKind(any(), any(), any(), any()); return ddlClient; } catch (Exception e) { throw new RuntimeException(e); @@ -135,6 +140,7 @@ private DdlBatch createSubject(DdlClient ddlClient, DatabaseClient dbClient) { .setDatabaseClient(dbClient) .withStatementExecutor(new StatementExecutor()) .setSpan(Span.getInvalid()) + .setConnectionState(new ConnectionState(new HashMap<>())) .build(); } @@ -256,9 +262,12 @@ public void testGetStateAndIsActive() { assertThat(batch.isActive(), is(false)); DdlClient client = mock(DdlClient.class); - SpannerException exception = mock(SpannerException.class); - when(exception.getErrorCode()).thenReturn(ErrorCode.FAILED_PRECONDITION); + SpannerException exception = + SpannerExceptionFactory.newSpannerException(ErrorCode.FAILED_PRECONDITION, "test"); doThrow(exception).when(client).executeDdl(anyList(), isNull()); + doCallRealMethod() + .when(client) + .runWithRetryForMissingDefaultSequenceKind(any(), any(), any(), any()); batch = createSubject(client); assertThat(batch.getState(), is(UnitOfWorkState.STARTED)); assertThat(batch.isActive(), is(true)); @@ -380,6 +389,7 @@ public void testRunBatch() { .withStatementExecutor(new StatementExecutor()) .setSpan(Span.getInvalid()) .setProtoDescriptors(null) + .setConnectionState(new ConnectionState(new HashMap<>())) .build(); batch.executeDdlAsync(CallType.SYNC, statement); batch.executeDdlAsync(CallType.SYNC, statement); @@ -406,6 +416,7 @@ public void testRunBatch() { .withStatementExecutor(new StatementExecutor()) .setSpan(Span.getInvalid()) .setProtoDescriptors(protoDescriptors) + .setConnectionState(new ConnectionState(new HashMap<>())) .build(); batch.executeDdlAsync(CallType.SYNC, statement); batch.executeDdlAsync(CallType.SYNC, statement); @@ -437,6 +448,7 @@ public void testUpdateCount() throws InterruptedException, ExecutionException { .setDdlClient(client) .setDatabaseClient(mock(DatabaseClient.class)) .setSpan(Span.getInvalid()) + .setConnectionState(new ConnectionState(new HashMap<>())) .build(); batch.executeDdlAsync( CallType.SYNC, @@ -469,6 +481,9 @@ public void testFailedUpdateCount() throws InterruptedException, ExecutionExcept new ExecutionException( "ddl statement failed", Status.INVALID_ARGUMENT.asRuntimeException())); when(operationFuture.getMetadata()).thenReturn(metadataFuture); + doCallRealMethod() + .when(client) + .runWithRetryForMissingDefaultSequenceKind(any(), any(), any(), any()); when(client.executeDdl(argThat(isListOfStringsWithSize(2)), isNull())) .thenReturn(operationFuture); DdlBatch batch = @@ -477,6 +492,7 @@ public void testFailedUpdateCount() throws InterruptedException, ExecutionExcept .setDdlClient(client) .setDatabaseClient(mock(DatabaseClient.class)) .setSpan(Span.getInvalid()) + .setConnectionState(new ConnectionState(new HashMap<>())) .build(); batch.executeDdlAsync( CallType.SYNC, @@ -499,6 +515,9 @@ public void testFailedUpdateCount() throws InterruptedException, ExecutionExcept @Test public void testFailedAfterFirstStatement() throws InterruptedException, ExecutionException { DdlClient client = mock(DdlClient.class); + doCallRealMethod() + .when(client) + .runWithRetryForMissingDefaultSequenceKind(any(), any(), any(), any()); UpdateDatabaseDdlMetadata metadata = UpdateDatabaseDdlMetadata.newBuilder() .addCommitTimestamps( @@ -521,6 +540,7 @@ public void testFailedAfterFirstStatement() throws InterruptedException, Executi .setDdlClient(client) .setDatabaseClient(mock(DatabaseClient.class)) .setSpan(Span.getInvalid()) + .setConnectionState(new ConnectionState(new HashMap<>())) .build(); batch.executeDdlAsync( CallType.SYNC, diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlTest.java index 44a2f4d9ff7..209796b9873 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/DdlTest.java @@ -17,15 +17,20 @@ package com.google.cloud.spanner.connection; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import com.google.cloud.spanner.ErrorCode; +import com.google.cloud.spanner.MissingDefaultSequenceKindException; +import com.google.cloud.spanner.SpannerBatchUpdateException; import com.google.cloud.spanner.SpannerException; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.connection.StatementResult.ResultType; import com.google.longrunning.Operation; +import com.google.protobuf.AbstractMessage; import com.google.protobuf.Any; import com.google.protobuf.Empty; +import com.google.rpc.Code; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlRequest; import com.google.spanner.v1.CommitRequest; @@ -65,6 +70,21 @@ private void addUpdateDdlResponse() { .build()); } + private void addUpdateDdlResponse(com.google.rpc.Status error) { + mockDatabaseAdmin.addResponse( + Operation.newBuilder() + .setMetadata( + Any.pack( + UpdateDatabaseDdlMetadata.newBuilder() + .setDatabase("projects/proj/instances/inst/databases/db") + .build())) + .setName("projects/proj/instances/inst/databases/db/operations/1") + .setDone(true) + // .setResponse(Any.pack(Empty.getDefaultInstance())) + .setError(error) + .build()); + } + @Test public void testSingleAnalyzeStatement() { addUpdateDdlResponse(); @@ -230,4 +250,114 @@ public void testDdlBatchInTransaction() { } } } + + @Test + public void testMissingDefaultSequenceKindException() { + addUpdateDdlResponse( + com.google.rpc.Status.newBuilder() + .setCode(Code.INVALID_ARGUMENT_VALUE) + .setMessage( + "The sequence kind of an identity column id2 is not specified. " + + "Please specify the sequence kind explicitly or set the database option `default_sequence_kind`.") + .build()); + try (Connection connection = createConnection()) { + assertNull(connection.getDefaultSequenceKind()); + assertThrows( + MissingDefaultSequenceKindException.class, + () -> + connection.execute( + Statement.of("create table foo (id2 int64 auto_increment primary key"))); + } + // The request should not be retried. + assertEquals(1, mockDatabaseAdmin.getRequests().size()); + } + + @Test + public void testSetsDefaultSequenceKindAndRetriesStatement() { + addUpdateDdlResponse( + com.google.rpc.Status.newBuilder() + .setCode(Code.INVALID_ARGUMENT_VALUE) + .setMessage( + "The sequence kind of an identity column id2 is not specified. " + + "Please specify the sequence kind explicitly or set the database option `default_sequence_kind`.") + .build()); + // This will be the response for the 'alter database' statement. + addUpdateDdlResponse(); + // This will be the response for the 'create table' statement after the retry. + addUpdateDdlResponse(); + try (Connection connection = createConnection()) { + connection.setDefaultSequenceKind("bit_reversed_positive"); + connection.execute(Statement.of("create table foo (id2 int64 auto_increment primary key")); + } + List requests = mockDatabaseAdmin.getRequests(); + assertEquals(3, requests.size()); + assertEquals( + "create table foo (id2 int64 auto_increment primary key", + ((UpdateDatabaseDdlRequest) requests.get(0)).getStatements(0)); + assertEquals( + "alter database `db` set options (default_sequence_kind='bit_reversed_positive')", + ((UpdateDatabaseDdlRequest) requests.get(1)).getStatements(0)); + assertEquals( + "create table foo (id2 int64 auto_increment primary key", + ((UpdateDatabaseDdlRequest) requests.get(2)).getStatements(0)); + } + + @Test + public void testMissingDefaultSequenceKindExceptionInBatch() { + addUpdateDdlResponse( + com.google.rpc.Status.newBuilder() + .setCode(Code.INVALID_ARGUMENT_VALUE) + .setMessage( + "The sequence kind of an identity column id2 is not specified. " + + "Please specify the sequence kind explicitly or set the database option `default_sequence_kind`.") + .build()); + try (Connection connection = createConnection()) { + assertNull(connection.getDefaultSequenceKind()); + connection.startBatchDdl(); + connection.execute(Statement.of("create table foo (id2 int64 auto_increment primary key")); + SpannerBatchUpdateException exception = + assertThrows(SpannerBatchUpdateException.class, connection::runBatch); + } + // The request should not be retried. + assertEquals(1, mockDatabaseAdmin.getRequests().size()); + } + + @Test + public void testSetsDefaultSequenceKindAndRetriesBatch() { + addUpdateDdlResponse( + com.google.rpc.Status.newBuilder() + .setCode(Code.INVALID_ARGUMENT_VALUE) + .setMessage( + "The sequence kind of an identity column id2 is not specified. " + + "Please specify the sequence kind explicitly or set the database option `default_sequence_kind`.") + .build()); + // This will be the response for the 'alter database' statement. + addUpdateDdlResponse(); + // This will be the response for the 'create table' statements after the retry. + addUpdateDdlResponse(); + try (Connection connection = createConnection()) { + connection.setDefaultSequenceKind("bit_reversed_positive"); + connection.startBatchDdl(); + connection.execute(Statement.of("create table foo (id1 int64 auto_increment primary key")); + connection.execute(Statement.of("create table bar (id2 int64 auto_increment primary key")); + connection.runBatch(); + } + List requests = mockDatabaseAdmin.getRequests(); + assertEquals(3, requests.size()); + assertEquals( + "create table foo (id1 int64 auto_increment primary key", + ((UpdateDatabaseDdlRequest) requests.get(0)).getStatements(0)); + assertEquals( + "create table bar (id2 int64 auto_increment primary key", + ((UpdateDatabaseDdlRequest) requests.get(0)).getStatements(1)); + assertEquals( + "alter database `db` set options (default_sequence_kind='bit_reversed_positive')", + ((UpdateDatabaseDdlRequest) requests.get(1)).getStatements(0)); + assertEquals( + "create table foo (id1 int64 auto_increment primary key", + ((UpdateDatabaseDdlRequest) requests.get(0)).getStatements(0)); + assertEquals( + "create table bar (id2 int64 auto_increment primary key", + ((UpdateDatabaseDdlRequest) requests.get(0)).getStatements(1)); + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java index 0e2a322023d..5ac926d5956 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/SingleUseTransactionTest.java @@ -17,6 +17,9 @@ package com.google.cloud.spanner.connection; import static com.google.cloud.spanner.SpannerApiFutures.get; +import static com.google.cloud.spanner.connection.ConnectionProperties.AUTOCOMMIT_DML_MODE; +import static com.google.cloud.spanner.connection.ConnectionProperties.READONLY; +import static com.google.cloud.spanner.connection.ConnectionProperties.READ_ONLY_STALENESS; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -25,6 +28,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyList; import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -55,6 +59,7 @@ import com.google.cloud.spanner.TransactionRunner; import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement; import com.google.cloud.spanner.connection.AbstractStatementParser.StatementType; +import com.google.cloud.spanner.connection.ConnectionProperty.Context; import com.google.cloud.spanner.connection.StatementExecutor.StatementTimeout; import com.google.cloud.spanner.connection.UnitOfWork.CallType; import com.google.common.base.Preconditions; @@ -66,6 +71,7 @@ import java.util.Arrays; import java.util.Calendar; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.Test; @@ -306,6 +312,9 @@ private DdlClient createDefaultMockDdlClient() { when(operation.get()).thenReturn(null); when(ddlClient.executeDdl(anyString(), any())).thenCallRealMethod(); when(ddlClient.executeDdl(anyList(), any())).thenReturn(operation); + doCallRealMethod() + .when(ddlClient) + .runWithRetryForMissingDefaultSequenceKind(any(), any(), any(), any()); return ddlClient; } catch (Exception e) { throw new RuntimeException(e); @@ -418,6 +427,11 @@ private SingleUseTransaction createSubject( .thenThrow( SpannerExceptionFactory.newSpannerException(ErrorCode.UNKNOWN, "invalid update")); + ConnectionState connectionState = new ConnectionState(new HashMap<>()); + connectionState.setValue(AUTOCOMMIT_DML_MODE, dmlMode, Context.STARTUP, false); + connectionState.setValue(READONLY, readOnly, Context.STARTUP, false); + connectionState.setValue(READ_ONLY_STALENESS, staleness, Context.STARTUP, false); + when(dbClient.readWriteTransaction()) .thenAnswer( new Answer() { @@ -473,9 +487,7 @@ public TransactionRunner allowNestedTransaction() { .setDatabaseClient(dbClient) .setBatchClient(mock(BatchClient.class)) .setDdlClient(ddlClient) - .setAutocommitDmlMode(dmlMode) - .setReadOnly(readOnly) - .setReadOnlyStaleness(staleness) + .setConnectionState(connectionState) .setStatementTimeout( timeout == 0L ? nullTimeout() : timeout(timeout, TimeUnit.MILLISECONDS)) .withStatementExecutor(executor) @@ -664,14 +676,18 @@ public void testExecuteQueryWithOptionsTest() { when(tx.executeQuery(Statement.of(sql), option)).thenReturn(mock(ResultSet.class)); when(client.singleUseReadOnlyTransaction(TimestampBound.strong())).thenReturn(tx); + ConnectionState connectionState = new ConnectionState(new HashMap<>()); + connectionState.setValue( + AUTOCOMMIT_DML_MODE, AutocommitDmlMode.TRANSACTIONAL, Context.STARTUP, false); + connectionState.setValue(READ_ONLY_STALENESS, TimestampBound.strong(), Context.STARTUP, false); + SingleUseTransaction transaction = SingleUseTransaction.newBuilder() .setDatabaseClient(client) .setBatchClient(mock(BatchClient.class)) .setDdlClient(mock(DdlClient.class)) - .setAutocommitDmlMode(AutocommitDmlMode.TRANSACTIONAL) + .setConnectionState(connectionState) .withStatementExecutor(executor) - .setReadOnlyStaleness(TimestampBound.strong()) .setSpan(Span.getInvalid()) .build(); assertThat( diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDdlTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDdlTest.java index 7a9c5aa9262..affc7ad2a18 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDdlTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/it/ITDdlTest.java @@ -16,16 +16,31 @@ package com.google.cloud.spanner.connection.it; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseAdminClient; import com.google.cloud.spanner.DatabaseNotFoundException; +import com.google.cloud.spanner.Dialect; +import com.google.cloud.spanner.MissingDefaultSequenceKindException; import com.google.cloud.spanner.ParallelIntegrationTest; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.SpannerBatchUpdateException; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.connection.Connection; +import com.google.cloud.spanner.connection.ConnectionOptions; import com.google.cloud.spanner.connection.ITAbstractSpannerTest; import com.google.cloud.spanner.connection.SqlScriptVerifier; +import com.google.cloud.spanner.testing.EmulatorSpannerHelper; +import java.util.Arrays; +import java.util.Collections; +import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -35,6 +50,16 @@ @Category(ParallelIntegrationTest.class) @RunWith(JUnit4.class) public class ITDdlTest extends ITAbstractSpannerTest { + @BeforeClass + public static void setup() { + // This overrides the default behavior that creates a single database for the test class. This + // test needs a separate database per method. + } + + @Before + public void createTestDatabase() { + database = env.getTestHelper().createTestDatabase(); + } @Test public void testSqlScript() throws Exception { @@ -57,4 +82,131 @@ public void testCreateDatabase() { client.dropDatabase(instance, name); } } + + @Test + public void testDefaultSequenceKind() { + try (Connection connection = createConnection()) { + Statement statement = + Statement.of( + "create table test (id int64 auto_increment primary key, value string(max))"); + + // Creating a table with an auto_increment column fails if no default sequence kind has been + // set. + assertNull(connection.getDefaultSequenceKind()); + assertThrows(MissingDefaultSequenceKindException.class, () -> connection.execute(statement)); + + // Setting a default sequence kind on the connection should make the statement succeed. + connection.setDefaultSequenceKind("bit_reversed_positive"); + connection.execute(statement); + + assertEquals( + 1L, connection.executeUpdate(Statement.of("insert into test (value) values ('One')"))); + try (ResultSet resultSet = connection.executeQuery(Statement.of("select * from test"))) { + assertTrue(resultSet.next()); + assertEquals("One", resultSet.getString(1)); + assertFalse(resultSet.next()); + } + } + } + + @Test + public void testDefaultSequenceKind_PostgreSQL() throws Exception { + DatabaseAdminClient client = getTestEnv().getTestHelper().getClient().getDatabaseAdminClient(); + String instance = getTestEnv().getTestHelper().getInstanceId().getInstance(); + String name = getTestEnv().getTestHelper().getUniqueDatabaseId(); + + Database database = + client + .createDatabase( + instance, + "create database \"" + name + "\"", + Dialect.POSTGRESQL, + Collections.emptyList()) + .get(); + + StringBuilder url = extractConnectionUrl(getTestEnv().getTestHelper().getOptions(), database); + ConnectionOptions.Builder builder = ConnectionOptions.newBuilder().setUri(url.toString()); + if (hasValidKeyFile()) { + builder.setCredentialsUrl(getKeyFile()); + } + ConnectionOptions options = builder.build(); + + try (Connection connection = options.getConnection()) { + Statement statement = + Statement.of("create table test (id serial primary key, value varchar)"); + + // Creating a table with an auto_increment column fails if no default sequence kind has been + // set. + assertNull(connection.getDefaultSequenceKind()); + assertThrows(MissingDefaultSequenceKindException.class, () -> connection.execute(statement)); + + // Setting a default sequence kind on the connection should make the statement succeed. + connection.setDefaultSequenceKind("bit_reversed_positive"); + connection.execute(statement); + + assertEquals( + 1L, connection.executeUpdate(Statement.of("insert into test (value) values ('One')"))); + try (ResultSet resultSet = connection.executeQuery(Statement.of("select * from test"))) { + assertTrue(resultSet.next()); + assertEquals("One", resultSet.getString(1)); + assertFalse(resultSet.next()); + } + } finally { + client.dropDatabase(instance, name); + } + } + + @Test + public void testDefaultSequenceKindInBatch() { + try (Connection connection = createConnection()) { + Statement statement1 = + Statement.of("create table testseq1 (id1 int64 primary key, value string(max))"); + Statement statement2 = + Statement.of( + "create table testseq2 (id2 int64 auto_increment primary key, value string(max))"); + + // Creating a table with an auto_increment column fails if no default sequence kind has been + // set. + assertNull(connection.getDefaultSequenceKind()); + connection.startBatchDdl(); + connection.execute(statement1); + connection.execute(statement2); + SpannerBatchUpdateException exception = + assertThrows(SpannerBatchUpdateException.class, connection::runBatch); + long updateCount = Arrays.stream(exception.getUpdateCounts()).sum(); + // The emulator refuses the entire batch. Spanner executes the first statement and fails on + // the second statement. + if (EmulatorSpannerHelper.isUsingEmulator()) { + assertEquals(0, updateCount); + } else { + assertEquals(1, updateCount); + } + + // Setting a default sequence kind on the connection should make the statement succeed. + connection.setDefaultSequenceKind("bit_reversed_positive"); + connection.startBatchDdl(); + if (updateCount == 0) { + connection.execute(statement1); + } + connection.execute(statement2); + connection.runBatch(); + } + } + + @Test + public void testDefaultSequenceKindRetriesBatchCorrectly() { + try (Connection connection = createConnection()) { + Statement statement1 = + Statement.of("create table testseq1 (id1 int64 primary key, value string(max))"); + Statement statement2 = + Statement.of( + "create table testseq2 (id2 int64 auto_increment primary key, value string(max))"); + + connection.setDefaultSequenceKind("bit_reversed_positive"); + connection.startBatchDdl(); + connection.execute(statement1); + connection.execute(statement2); + connection.runBatch(); + } + } } From 6c2848b108c1d2a430b46350ec54108c3e1e8a37 Mon Sep 17 00:00:00 2001 From: Sagnik Ghosh Date: Thu, 27 Feb 2025 13:33:29 +0530 Subject: [PATCH 09/12] chore: support spanner prefix jdbc url (#3654) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(spanner): support spanner prefix jdbc url * support for both prefix spanner/cloudspanner * unit test for change in existing pattern --------- Co-authored-by: Knut Olav Løite --- .../spanner/connection/ConnectionOptions.java | 4 ++-- .../connection/ConnectionOptionsTest.java | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java index f63d8f1f10c..b766545a799 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java @@ -642,10 +642,10 @@ private Builder() {} /** Spanner {@link ConnectionOptions} URI format. */ public static final String SPANNER_URI_FORMAT = - "(?:cloudspanner:)(?//[\\w.-]+(?:\\.[\\w\\.-]+)*[\\w\\-\\._~:/?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=.]+)?/projects/(?(([a-z]|[-.:]|[0-9])+|(DEFAULT_PROJECT_ID)))(/instances/(?([a-z]|[-]|[0-9])+)(/databases/(?([a-z]|[-]|[_]|[0-9])+))?)?(?:[?|;].*)?"; + "(?:(?:spanner|cloudspanner):)(?//[\\w.-]+(?:\\.[\\w\\.-]+)*[\\w\\-\\._~:/?#\\[\\]@!\\$&'\\(\\)\\*\\+,;=.]+)?/projects/(?(([a-z]|[-.:]|[0-9])+|(DEFAULT_PROJECT_ID)))(/instances/(?([a-z]|[-]|[0-9])+)(/databases/(?([a-z]|[-]|[_]|[0-9])+))?)?(?:[?|;].*)?"; public static final String EXTERNAL_HOST_FORMAT = - "(?:cloudspanner:)(?//[\\w.-]+(?::\\d+)?)(/instances/(?[a-z0-9-]+))?(/databases/(?[a-z0-9_-]+))(?:[?;].*)?"; + "(?:(?:spanner|cloudspanner):)(?//[\\w.-]+(?::\\d+)?)(/instances/(?[a-z0-9-]+))?(/databases/(?[a-z0-9_-]+))(?:[?;].*)?"; private static final String SPANNER_URI_REGEX = "(?is)^" + SPANNER_URI_FORMAT + "$"; @VisibleForTesting diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java index 69c4a010327..76771ffcc9b 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java @@ -1247,5 +1247,27 @@ public void testExternalHostPatterns() { Matcher matcherWithoutHost = EXTERNAL_HOST_PATTERN.matcher("cloudspanner:/instances/default/databases/singers-db"); assertFalse(matcherWithoutHost.matches()); + Matcher matcherWithPrefixSpanner = + EXTERNAL_HOST_PATTERN.matcher("spanner://localhost:15000/databases/test-db"); + assertTrue(matcherWithPrefixSpanner.matches()); + assertNull(matcherWithPrefixSpanner.group("INSTANCEGROUP")); + assertEquals("test-db", matcherWithPrefixSpanner.group("DATABASEGROUP")); + } + + @Test + public void testBuildWithValidURIWithPrefixSpanner() { + ConnectionOptions.Builder builder = ConnectionOptions.newBuilder(); + builder.setUri( + "spanner:/projects/test-project-123/instances/test-instance-123/databases/test-database-123?autocommit=false;readonly=true"); + builder.setCredentialsUrl(FILE_TEST_PATH); + ConnectionOptions options = builder.build(); + assertThat(options.getHost()).isEqualTo(DEFAULT_HOST); + assertThat(options.getProjectId()).isEqualTo("test-project-123"); + assertThat(options.getInstanceId()).isEqualTo("test-instance-123"); + assertThat(options.getDatabaseName()).isEqualTo("test-database-123"); + assertThat(options.getCredentials()) + .isEqualTo(new CredentialsService().createCredentials(FILE_TEST_PATH)); + assertThat(options.isAutocommit()).isEqualTo(false); + assertThat(options.isReadOnly()).isEqualTo(true); } } From 57497ad00c62f152f493645f382530cf0eedf19e Mon Sep 17 00:00:00 2001 From: cloud-java-bot <122572305+cloud-java-bot@users.noreply.github.com> Date: Thu, 27 Feb 2025 04:46:36 -0500 Subject: [PATCH 10/12] chore: Update generation configuration at Thu Feb 27 02:25:45 UTC 2025 (#3664) --- .github/workflows/hermetic_library_generation.yaml | 2 +- generation_config.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/hermetic_library_generation.yaml b/.github/workflows/hermetic_library_generation.yaml index 545f190487a..5ad2a254b92 100644 --- a/.github/workflows/hermetic_library_generation.yaml +++ b/.github/workflows/hermetic_library_generation.yaml @@ -37,7 +37,7 @@ jobs: with: fetch-depth: 0 token: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }} - - uses: googleapis/sdk-platform-java/.github/scripts@v2.53.0 + - uses: googleapis/sdk-platform-java/.github/scripts@v2.54.0 if: env.SHOULD_RUN == 'true' with: base_ref: ${{ github.base_ref }} diff --git a/generation_config.yaml b/generation_config.yaml index 0c02ec882aa..3eb07cc0953 100644 --- a/generation_config.yaml +++ b/generation_config.yaml @@ -1,5 +1,5 @@ -gapic_generator_version: 2.53.0 -googleapis_commitish: fbbbf5023815f9a662c85aa8af8f3b72467fcb6f +gapic_generator_version: 2.54.0 +googleapis_commitish: 554575ee8d01d277344ec704e0561e9abc7f57f3 libraries_bom_version: 26.55.0 libraries: - api_shortname: spanner From 35435488f87ebd59179698e8f74578b41eb219da Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 27 Feb 2025 18:34:08 +0100 Subject: [PATCH 11/12] deps: update dependency com.google.cloud:sdk-platform-java-config to v3.44.0 (#3665) --- .github/workflows/unmanaged_dependency_check.yaml | 2 +- .kokoro/presubmit/graalvm-native-17.cfg | 2 +- .kokoro/presubmit/graalvm-native.cfg | 2 +- google-cloud-spanner-bom/pom.xml | 2 +- pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/unmanaged_dependency_check.yaml b/.github/workflows/unmanaged_dependency_check.yaml index 0f6016e7ca3..8e2311b0d75 100644 --- a/.github/workflows/unmanaged_dependency_check.yaml +++ b/.github/workflows/unmanaged_dependency_check.yaml @@ -17,6 +17,6 @@ jobs: # repository .kokoro/build.sh - name: Unmanaged dependency check - uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.43.0 + uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.44.0 with: bom-path: google-cloud-spanner-bom/pom.xml diff --git a/.kokoro/presubmit/graalvm-native-17.cfg b/.kokoro/presubmit/graalvm-native-17.cfg index 8d3f11dc47e..728751d048e 100644 --- a/.kokoro/presubmit/graalvm-native-17.cfg +++ b/.kokoro/presubmit/graalvm-native-17.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.43.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.44.0" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native.cfg b/.kokoro/presubmit/graalvm-native.cfg index f78bafd26ec..39151469c78 100644 --- a/.kokoro/presubmit/graalvm-native.cfg +++ b/.kokoro/presubmit/graalvm-native.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.43.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.44.0" } env_vars: { diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index 5bfc2df28f4..79f5ce3f930 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -8,7 +8,7 @@ com.google.cloud sdk-platform-java-config - 3.43.0 + 3.44.0 Google Cloud Spanner BOM diff --git a/pom.xml b/pom.xml index 5c3e2d561b0..7456e6acacb 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.google.cloud sdk-platform-java-config - 3.43.0 + 3.44.0 From 0d31b272650b7115393d9e71f361eda4d908a308 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 00:02:09 +0530 Subject: [PATCH 12/12] chore(main): release 6.88.0 (#3663) * chore(main): release 6.88.0 * chore: generate libraries at Thu Feb 27 17:35:12 UTC 2025 --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: cloud-java-bot --- CHANGELOG.md | 21 +++++++++++++++++++ README.md | 6 +++--- benchmarks/pom.xml | 2 +- google-cloud-spanner-bom/pom.xml | 18 ++++++++-------- google-cloud-spanner-executor/pom.xml | 4 ++-- google-cloud-spanner/pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- grpc-google-cloud-spanner-executor-v1/pom.xml | 4 ++-- grpc-google-cloud-spanner-v1/pom.xml | 4 ++-- pom.xml | 20 +++++++++--------- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- proto-google-cloud-spanner-v1/pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 20 +++++++++--------- 17 files changed, 75 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4b269263e9..e094f71952c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## [6.88.0](https://github.com/googleapis/java-spanner/compare/v6.87.0...v6.88.0) (2025-02-27) + + +### Features + +* Add a last field in the PartialResultSet ([7c714be](https://github.com/googleapis/java-spanner/commit/7c714be10eb345f2d8f566d752f6de615061c4da)) +* Automatically set default sequence kind in JDBC and PGAdapter ([#3658](https://github.com/googleapis/java-spanner/issues/3658)) ([e8abf33](https://github.com/googleapis/java-spanner/commit/e8abf338b85e95f185ab2875a804134523f84de3)) +* Default authentication support for external hosts ([#3656](https://github.com/googleapis/java-spanner/issues/3656)) ([ace11d5](https://github.com/googleapis/java-spanner/commit/ace11d5d928fb567b16560263ae95aa9cd916e22)) +* **spanner:** A new enum `IsolationLevel` is added ([3fd33ba](https://github.com/googleapis/java-spanner/commit/3fd33ba9c5fab43ed475ed3cff9d60c008843981)) +* **spanner:** Add instance partitions field in backup proto ([3fd33ba](https://github.com/googleapis/java-spanner/commit/3fd33ba9c5fab43ed475ed3cff9d60c008843981)) + + +### Bug Fixes + +* **deps:** Update the Java code generator (gapic-generator-java) to 2.54.0 ([57497ad](https://github.com/googleapis/java-spanner/commit/57497ad00c62f152f493645f382530cf0eedf19e)) + + +### Dependencies + +* Update dependency com.google.cloud:sdk-platform-java-config to v3.44.0 ([#3665](https://github.com/googleapis/java-spanner/issues/3665)) ([3543548](https://github.com/googleapis/java-spanner/commit/35435488f87ebd59179698e8f74578b41eb219da)) + ## [6.87.0](https://github.com/googleapis/java-spanner/compare/v6.86.0...v6.87.0) (2025-02-20) diff --git a/README.md b/README.md index 5f828e75a23..4f006df2195 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.87.0' +implementation 'com.google.cloud:google-cloud-spanner:6.88.0' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.87.0" +libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.88.0" ``` ## Authentication @@ -727,7 +727,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.87.0 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-spanner/6.88.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 5dc655d72c7..9e8ea9ea11c 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -24,7 +24,7 @@ com.google.cloud google-cloud-spanner-parent - 6.87.1-SNAPSHOT + 6.88.0 diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index 79f5ce3f930..6556b425e43 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.87.1-SNAPSHOT + 6.88.0 pom com.google.cloud @@ -53,43 +53,43 @@ com.google.cloud google-cloud-spanner - 6.87.1-SNAPSHOT + 6.88.0 com.google.cloud google-cloud-spanner test-jar - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.87.1-SNAPSHOT + 6.88.0 diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index 118993fff25..642f599fc45 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.87.1-SNAPSHOT + 6.88.0 jar Google Cloud Spanner Executor com.google.cloud google-cloud-spanner-parent - 6.87.1-SNAPSHOT + 6.88.0 diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index 5b0e11894f6..a460cc33735 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.87.1-SNAPSHOT + 6.88.0 jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.87.1-SNAPSHOT + 6.88.0 google-cloud-spanner diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index ffded2f717f..1a625510f2e 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.87.1-SNAPSHOT + 6.88.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.87.1-SNAPSHOT + 6.88.0 diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index 82bbf6a83c8..94d4025e1fc 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.87.1-SNAPSHOT + 6.88.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.87.1-SNAPSHOT + 6.88.0 diff --git a/grpc-google-cloud-spanner-executor-v1/pom.xml b/grpc-google-cloud-spanner-executor-v1/pom.xml index 2601c52ae1f..0328646033d 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.87.1-SNAPSHOT + 6.88.0 grpc-google-cloud-spanner-executor-v1 GRPC library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.87.1-SNAPSHOT + 6.88.0 diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index d2fc10186b8..50ff4cc66cb 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.87.1-SNAPSHOT + 6.88.0 grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.87.1-SNAPSHOT + 6.88.0 diff --git a/pom.xml b/pom.xml index 7456e6acacb..92a7a25e071 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.87.1-SNAPSHOT + 6.88.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.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.87.1-SNAPSHOT + 6.88.0 com.google.cloud google-cloud-spanner - 6.87.1-SNAPSHOT + 6.88.0 diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index a8877ec4993..52a8916483c 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.87.1-SNAPSHOT + 6.88.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.87.1-SNAPSHOT + 6.88.0 diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index 2aabd553523..efd0e57ec4b 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.87.1-SNAPSHOT + 6.88.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.87.1-SNAPSHOT + 6.88.0 diff --git a/proto-google-cloud-spanner-executor-v1/pom.xml b/proto-google-cloud-spanner-executor-v1/pom.xml index 3420c2b4079..3d72023ac61 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.87.1-SNAPSHOT + 6.88.0 proto-google-cloud-spanner-executor-v1 Proto library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.87.1-SNAPSHOT + 6.88.0 diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index f92985f9730..4fc862e1b2c 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.87.1-SNAPSHOT + 6.88.0 proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.87.1-SNAPSHOT + 6.88.0 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index ea087ed0255..5c59f13a093 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -32,7 +32,7 @@ com.google.cloud google-cloud-spanner - 6.87.1-SNAPSHOT + 6.88.0 diff --git a/versions.txt b/versions.txt index 8ab160eb598..241218b5a59 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.87.0:6.87.1-SNAPSHOT -proto-google-cloud-spanner-v1:6.87.0:6.87.1-SNAPSHOT -proto-google-cloud-spanner-admin-database-v1:6.87.0:6.87.1-SNAPSHOT -grpc-google-cloud-spanner-v1:6.87.0:6.87.1-SNAPSHOT -grpc-google-cloud-spanner-admin-instance-v1:6.87.0:6.87.1-SNAPSHOT -grpc-google-cloud-spanner-admin-database-v1:6.87.0:6.87.1-SNAPSHOT -google-cloud-spanner:6.87.0:6.87.1-SNAPSHOT -google-cloud-spanner-executor:6.87.0:6.87.1-SNAPSHOT -proto-google-cloud-spanner-executor-v1:6.87.0:6.87.1-SNAPSHOT -grpc-google-cloud-spanner-executor-v1:6.87.0:6.87.1-SNAPSHOT +proto-google-cloud-spanner-admin-instance-v1:6.88.0:6.88.0 +proto-google-cloud-spanner-v1:6.88.0:6.88.0 +proto-google-cloud-spanner-admin-database-v1:6.88.0:6.88.0 +grpc-google-cloud-spanner-v1:6.88.0:6.88.0 +grpc-google-cloud-spanner-admin-instance-v1:6.88.0:6.88.0 +grpc-google-cloud-spanner-admin-database-v1:6.88.0:6.88.0 +google-cloud-spanner:6.88.0:6.88.0 +google-cloud-spanner-executor:6.88.0:6.88.0 +proto-google-cloud-spanner-executor-v1:6.88.0:6.88.0 +grpc-google-cloud-spanner-executor-v1:6.88.0:6.88.0