aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/cloud.google.com/go/spanner
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2024-09-10 12:16:33 +0200
committerTaras Madan <tarasmadan@google.com>2024-09-10 14:05:26 +0000
commitc97c816133b42257d0bcf1ee4bd178bb2a7a2b9e (patch)
tree0bcbc2e540bbf8f62f6c17887cdd53b8c2cee637 /vendor/cloud.google.com/go/spanner
parent54e657429ab892ad06c90cd7c1a4eb33ba93a3dc (diff)
vendor: update
Diffstat (limited to 'vendor/cloud.google.com/go/spanner')
-rw-r--r--vendor/cloud.google.com/go/spanner/CHANGES.md110
-rw-r--r--vendor/cloud.google.com/go/spanner/apiv1/spanner_client.go79
-rw-r--r--vendor/cloud.google.com/go/spanner/apiv1/spannerpb/commit_response.pb.go12
-rw-r--r--vendor/cloud.google.com/go/spanner/apiv1/spannerpb/keys.pb.go14
-rw-r--r--vendor/cloud.google.com/go/spanner/apiv1/spannerpb/mutation.pb.go16
-rw-r--r--vendor/cloud.google.com/go/spanner/apiv1/spannerpb/query_plan.pb.go16
-rw-r--r--vendor/cloud.google.com/go/spanner/apiv1/spannerpb/result_set.pb.go18
-rw-r--r--vendor/cloud.google.com/go/spanner/apiv1/spannerpb/spanner.pb.go1098
-rw-r--r--vendor/cloud.google.com/go/spanner/apiv1/spannerpb/transaction.pb.go26
-rw-r--r--vendor/cloud.google.com/go/spanner/apiv1/spannerpb/type.pb.go14
-rw-r--r--vendor/cloud.google.com/go/spanner/batch.go2
-rw-r--r--vendor/cloud.google.com/go/spanner/client.go277
-rw-r--r--vendor/cloud.google.com/go/spanner/emulator_test.sh6
-rw-r--r--vendor/cloud.google.com/go/spanner/errors.go6
-rw-r--r--vendor/cloud.google.com/go/spanner/internal/version.go2
-rw-r--r--vendor/cloud.google.com/go/spanner/key.go10
-rw-r--r--vendor/cloud.google.com/go/spanner/mutation.go2
-rw-r--r--vendor/cloud.google.com/go/spanner/ot_metrics.go28
-rw-r--r--vendor/cloud.google.com/go/spanner/pdml.go7
-rw-r--r--vendor/cloud.google.com/go/spanner/protoutils.go25
-rw-r--r--vendor/cloud.google.com/go/spanner/read.go6
-rw-r--r--vendor/cloud.google.com/go/spanner/retry.go8
-rw-r--r--vendor/cloud.google.com/go/spanner/row.go2
-rw-r--r--vendor/cloud.google.com/go/spanner/session.go439
-rw-r--r--vendor/cloud.google.com/go/spanner/sessionclient.go80
-rw-r--r--vendor/cloud.google.com/go/spanner/statement.go4
-rw-r--r--vendor/cloud.google.com/go/spanner/stats.go14
-rw-r--r--vendor/cloud.google.com/go/spanner/timestampbound.go4
-rw-r--r--vendor/cloud.google.com/go/spanner/transaction.go125
-rw-r--r--vendor/cloud.google.com/go/spanner/value.go531
30 files changed, 2236 insertions, 745 deletions
diff --git a/vendor/cloud.google.com/go/spanner/CHANGES.md b/vendor/cloud.google.com/go/spanner/CHANGES.md
index c7ba9674f..05453b9d0 100644
--- a/vendor/cloud.google.com/go/spanner/CHANGES.md
+++ b/vendor/cloud.google.com/go/spanner/CHANGES.md
@@ -1,5 +1,115 @@
# Changes
+## [1.67.0](https://github.com/googleapis/google-cloud-go/compare/spanner/v1.66.0...spanner/v1.67.0) (2024-08-15)
+
+
+### Features
+
+* **spanner/admin/database:** Add resource reference annotation to backup schedules ([#10677](https://github.com/googleapis/google-cloud-go/issues/10677)) ([6593c0d](https://github.com/googleapis/google-cloud-go/commit/6593c0d62d48751c857bce3d3f858127467a4489))
+* **spanner/admin/instance:** Add edition field to the instance proto ([6593c0d](https://github.com/googleapis/google-cloud-go/commit/6593c0d62d48751c857bce3d3f858127467a4489))
+* **spanner:** Support commit options in mutation operations. ([#10668](https://github.com/googleapis/google-cloud-go/issues/10668)) ([62a56f9](https://github.com/googleapis/google-cloud-go/commit/62a56f953d3b8fe82083c42926831c2728312b9c))
+
+
+### Bug Fixes
+
+* **spanner/test/opentelemetry/test:** Update google.golang.org/api to v0.191.0 ([5b32644](https://github.com/googleapis/google-cloud-go/commit/5b32644eb82eb6bd6021f80b4fad471c60fb9d73))
+* **spanner:** Update google.golang.org/api to v0.191.0 ([5b32644](https://github.com/googleapis/google-cloud-go/commit/5b32644eb82eb6bd6021f80b4fad471c60fb9d73))
+
+
+### Documentation
+
+* **spanner/admin/database:** Add an example to filter backups based on schedule name ([6593c0d](https://github.com/googleapis/google-cloud-go/commit/6593c0d62d48751c857bce3d3f858127467a4489))
+
+## [1.66.0](https://github.com/googleapis/google-cloud-go/compare/spanner/v1.65.0...spanner/v1.66.0) (2024-08-07)
+
+
+### Features
+
+* **spanner/admin/database:** Add support for Cloud Spanner Incremental Backups ([d949cc0](https://github.com/googleapis/google-cloud-go/commit/d949cc0e5d44af62154d9d5fd393f25a852f93ed))
+* **spanner:** Add support of multiplexed session support in writeAtleastOnce mutations ([#10646](https://github.com/googleapis/google-cloud-go/issues/10646)) ([54009ea](https://github.com/googleapis/google-cloud-go/commit/54009eab1c3b11a28531ad9e621917d01c9e5339))
+* **spanner:** Add support of using multiplexed session with ReadOnlyTransactions ([#10269](https://github.com/googleapis/google-cloud-go/issues/10269)) ([7797022](https://github.com/googleapis/google-cloud-go/commit/7797022e51d1ac07b8d919c421a8bfdf34a1d53c))
+
+## [1.65.0](https://github.com/googleapis/google-cloud-go/compare/spanner/v1.64.0...spanner/v1.65.0) (2024-07-29)
+
+
+### Features
+
+* **spanner/admin/database:** Add support for Cloud Spanner Scheduled Backups ([3b15f9d](https://github.com/googleapis/google-cloud-go/commit/3b15f9db9e0ee3bff3d8d5aafc82cdc2a31d60fc))
+* **spanner:** Add RESOURCE_EXHAUSTED to retryable transaction codes ([#10412](https://github.com/googleapis/google-cloud-go/issues/10412)) ([29b52dc](https://github.com/googleapis/google-cloud-go/commit/29b52dc40f3d1a6ffe7fa40e6142d8035c0d95ee))
+
+
+### Bug Fixes
+
+* **spanner/test:** Bump google.golang.org/api@v0.187.0 ([8fa9e39](https://github.com/googleapis/google-cloud-go/commit/8fa9e398e512fd8533fd49060371e61b5725a85b))
+* **spanner/test:** Bump google.golang.org/grpc@v1.64.1 ([8ecc4e9](https://github.com/googleapis/google-cloud-go/commit/8ecc4e9622e5bbe9b90384d5848ab816027226c5))
+* **spanner/test:** Update dependencies ([257c40b](https://github.com/googleapis/google-cloud-go/commit/257c40bd6d7e59730017cf32bda8823d7a232758))
+* **spanner:** Bump google.golang.org/api@v0.187.0 ([8fa9e39](https://github.com/googleapis/google-cloud-go/commit/8fa9e398e512fd8533fd49060371e61b5725a85b))
+* **spanner:** Bump google.golang.org/grpc@v1.64.1 ([8ecc4e9](https://github.com/googleapis/google-cloud-go/commit/8ecc4e9622e5bbe9b90384d5848ab816027226c5))
+* **spanner:** Fix negative values for max_in_use_sessions metrics [#10449](https://github.com/googleapis/google-cloud-go/issues/10449) ([#10508](https://github.com/googleapis/google-cloud-go/issues/10508)) ([4e180f4](https://github.com/googleapis/google-cloud-go/commit/4e180f4539012eb6e3d1d2788e68b291ef7230c3))
+* **spanner:** HealthCheck should not decrement num_in_use sessions ([#10480](https://github.com/googleapis/google-cloud-go/issues/10480)) ([9b2b47f](https://github.com/googleapis/google-cloud-go/commit/9b2b47f107153d624d56709d9a8e6a6b72c39447))
+* **spanner:** Update dependencies ([257c40b](https://github.com/googleapis/google-cloud-go/commit/257c40bd6d7e59730017cf32bda8823d7a232758))
+
+## [1.64.0](https://github.com/googleapis/google-cloud-go/compare/spanner/v1.63.0...spanner/v1.64.0) (2024-06-29)
+
+
+### Features
+
+* **spanner:** Add field lock_hint in spanner.proto ([3df3c04](https://github.com/googleapis/google-cloud-go/commit/3df3c04f0dffad3fa2fe272eb7b2c263801b9ada))
+* **spanner:** Add field order_by in spanner.proto ([3df3c04](https://github.com/googleapis/google-cloud-go/commit/3df3c04f0dffad3fa2fe272eb7b2c263801b9ada))
+* **spanner:** Add LockHint feature ([#10382](https://github.com/googleapis/google-cloud-go/issues/10382)) ([64bdcb1](https://github.com/googleapis/google-cloud-go/commit/64bdcb1a6a462d41a62d3badea6814425e271f22))
+* **spanner:** Add OrderBy feature ([#10289](https://github.com/googleapis/google-cloud-go/issues/10289)) ([07b8bd2](https://github.com/googleapis/google-cloud-go/commit/07b8bd2f5dc738e0293305dfc459c13632d5ea65))
+* **spanner:** Add support of checking row not found errors from ReadRow and ReadRowUsingIndex ([#10405](https://github.com/googleapis/google-cloud-go/issues/10405)) ([5cb0c26](https://github.com/googleapis/google-cloud-go/commit/5cb0c26013eeb3bbe51174bee628a20c2ec775e0))
+
+
+### Bug Fixes
+
+* **spanner:** Fix data-race caused by TrackSessionHandle ([#10321](https://github.com/googleapis/google-cloud-go/issues/10321)) ([23c5fff](https://github.com/googleapis/google-cloud-go/commit/23c5fffd06bcde408db50a981c015921cd4ecf0e)), refs [#10320](https://github.com/googleapis/google-cloud-go/issues/10320)
+* **spanner:** Fix negative values for max_in_use_sessions metrics ([#10449](https://github.com/googleapis/google-cloud-go/issues/10449)) ([a1e198a](https://github.com/googleapis/google-cloud-go/commit/a1e198a9b18bd2f92c3438e4f609412047f8ccf4))
+* **spanner:** Prevent possible panic for Session not found errors ([#10386](https://github.com/googleapis/google-cloud-go/issues/10386)) ([ba9711f](https://github.com/googleapis/google-cloud-go/commit/ba9711f87ec871153ae00cfd0827bce17c31ee9c)), refs [#10385](https://github.com/googleapis/google-cloud-go/issues/10385)
+
+## [1.63.0](https://github.com/googleapis/google-cloud-go/compare/spanner/v1.62.0...spanner/v1.63.0) (2024-05-24)
+
+
+### Features
+
+* **spanner:** Fix schema naming ([#10194](https://github.com/googleapis/google-cloud-go/issues/10194)) ([215e0c8](https://github.com/googleapis/google-cloud-go/commit/215e0c8125ea05246c834984bde1ca698c7dde4c))
+* **spanner:** Update go mod to use latest grpc lib ([#10218](https://github.com/googleapis/google-cloud-go/issues/10218)) ([adf91f9](https://github.com/googleapis/google-cloud-go/commit/adf91f9fd37faa39ec7c6f9200273220f65d2a82))
+
+## [1.62.0](https://github.com/googleapis/google-cloud-go/compare/spanner/v1.61.0...spanner/v1.62.0) (2024-05-15)
+
+
+### Features
+
+* **spanner/admin/database:** Add support for multi region encryption config ([3e25053](https://github.com/googleapis/google-cloud-go/commit/3e250530567ee81ed4f51a3856c5940dbec35289))
+* **spanner/executor:** Add QueryCancellationAction message in executor protos ([292e812](https://github.com/googleapis/google-cloud-go/commit/292e81231b957ae7ac243b47b8926564cee35920))
+* **spanner:** Add `RESOURCE_EXHAUSTED` to the list of retryable error codes ([1d757c6](https://github.com/googleapis/google-cloud-go/commit/1d757c66478963d6cbbef13fee939632c742759c))
+* **spanner:** Add support for Proto Columns ([#9315](https://github.com/googleapis/google-cloud-go/issues/9315)) ([3ffbbbe](https://github.com/googleapis/google-cloud-go/commit/3ffbbbe50225684f4211c6dbe3ca25acb3d02b8e))
+
+
+### Bug Fixes
+
+* **spanner:** Add ARRAY keywords to keywords ([#10079](https://github.com/googleapis/google-cloud-go/issues/10079)) ([8e675cd](https://github.com/googleapis/google-cloud-go/commit/8e675cd0ccf12c6912209aa5c56092db3716c40d))
+* **spanner:** Handle unused errors ([#10067](https://github.com/googleapis/google-cloud-go/issues/10067)) ([a0c097c](https://github.com/googleapis/google-cloud-go/commit/a0c097c724b609cfa428e69f89075f02a3782a7b))
+* **spanner:** Remove json-iterator dependency ([#10099](https://github.com/googleapis/google-cloud-go/issues/10099)) ([3917cca](https://github.com/googleapis/google-cloud-go/commit/3917ccac57c403b3b4d07514ac10a66a86e298c0)), refs [#9380](https://github.com/googleapis/google-cloud-go/issues/9380)
+* **spanner:** Update staleness bound ([#10118](https://github.com/googleapis/google-cloud-go/issues/10118)) ([c07f1e4](https://github.com/googleapis/google-cloud-go/commit/c07f1e47c06387b696abb1edbfa339b391ec1fd5))
+
+## [1.61.0](https://github.com/googleapis/google-cloud-go/compare/spanner/v1.60.0...spanner/v1.61.0) (2024-04-30)
+
+
+### Features
+
+* **spanner/admin/instance:** Adding `EXPECTED_FULFILLMENT_PERIOD` to the indicate instance creation times (with `FULFILLMENT_PERIOD_NORMAL` or `FULFILLMENT_PERIOD_EXTENDED` ENUM) with the extended instance creation time triggered by On-Demand Capacity... ([#9693](https://github.com/googleapis/google-cloud-go/issues/9693)) ([aa93790](https://github.com/googleapis/google-cloud-go/commit/aa93790132ba830b4c97d217ef02764e2fb1b8ea))
+* **spanner/executor:** Add SessionPoolOptions, SpannerOptions protos in executor protos ([2cdc40a](https://github.com/googleapis/google-cloud-go/commit/2cdc40a0b4288f5ab5f2b2b8f5c1d6453a9c81ec))
+* **spanner:** Add support for change streams transaction exclusion option ([#9779](https://github.com/googleapis/google-cloud-go/issues/9779)) ([979ce94](https://github.com/googleapis/google-cloud-go/commit/979ce94758442b1224a78a4f3b1f5d592ab51660))
+* **spanner:** Support MultiEndpoint ([#9565](https://github.com/googleapis/google-cloud-go/issues/9565)) ([0ac0d26](https://github.com/googleapis/google-cloud-go/commit/0ac0d265abedf946b05294ef874a892b2c5d6067))
+
+
+### Bug Fixes
+
+* **spanner/test/opentelemetry/test:** Bump x/net to v0.24.0 ([ba31ed5](https://github.com/googleapis/google-cloud-go/commit/ba31ed5fda2c9664f2e1cf972469295e63deb5b4))
+* **spanner:** Bump x/net to v0.24.0 ([ba31ed5](https://github.com/googleapis/google-cloud-go/commit/ba31ed5fda2c9664f2e1cf972469295e63deb5b4))
+* **spanner:** Fix uint8 conversion ([9221c7f](https://github.com/googleapis/google-cloud-go/commit/9221c7fa12cef9d5fb7ddc92f41f1d6204971c7b))
+
## [1.60.0](https://github.com/googleapis/google-cloud-go/compare/spanner/v1.59.0...spanner/v1.60.0) (2024-03-19)
diff --git a/vendor/cloud.google.com/go/spanner/apiv1/spanner_client.go b/vendor/cloud.google.com/go/spanner/apiv1/spanner_client.go
index af48f11c0..ccc6aa769 100644
--- a/vendor/cloud.google.com/go/spanner/apiv1/spanner_client.go
+++ b/vendor/cloud.google.com/go/spanner/apiv1/spanner_client.go
@@ -19,6 +19,7 @@ package spanner
import (
"bytes"
"context"
+ "errors"
"fmt"
"io"
"math"
@@ -84,6 +85,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -96,6 +98,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -108,6 +111,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -120,6 +124,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -132,6 +137,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -144,6 +150,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -157,6 +164,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -169,6 +177,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -182,6 +191,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -194,6 +204,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -206,6 +217,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -218,6 +230,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -230,6 +243,7 @@ func defaultCallOptions() *CallOptions {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.Unavailable,
+ codes.ResourceExhausted,
}, gax.Backoff{
Initial: 250 * time.Millisecond,
Max: 32000 * time.Millisecond,
@@ -251,7 +265,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
BatchCreateSessions: []gax.CallOption{
@@ -262,7 +277,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
GetSession: []gax.CallOption{
@@ -273,7 +289,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
ListSessions: []gax.CallOption{
@@ -284,7 +301,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
DeleteSession: []gax.CallOption{
@@ -295,7 +313,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
ExecuteSql: []gax.CallOption{
@@ -306,7 +325,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
ExecuteStreamingSql: []gax.CallOption{
@@ -320,7 +340,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
Read: []gax.CallOption{
@@ -331,7 +352,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
StreamingRead: []gax.CallOption{
@@ -345,7 +367,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
Commit: []gax.CallOption{
@@ -356,7 +379,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
Rollback: []gax.CallOption{
@@ -367,7 +391,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
PartitionQuery: []gax.CallOption{
@@ -378,7 +403,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
PartitionRead: []gax.CallOption{
@@ -389,7 +415,8 @@ func defaultRESTCallOptions() *CallOptions {
Max: 32000 * time.Millisecond,
Multiplier: 1.30,
},
- http.StatusServiceUnavailable)
+ http.StatusServiceUnavailable,
+ http.StatusTooManyRequests)
}),
},
BatchWrite: []gax.CallOption{
@@ -737,7 +764,9 @@ func (c *gRPCClient) Connection() *grpc.ClientConn {
func (c *gRPCClient) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", gax.GoVersion}, keyval...)
kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version)
- c.xGoogHeaders = []string{"x-goog-api-client", gax.XGoogHeader(kv...)}
+ c.xGoogHeaders = []string{
+ "x-goog-api-client", gax.XGoogHeader(kv...),
+ }
}
// Close closes the connection to the API service. The user should invoke this when
@@ -802,7 +831,9 @@ func defaultRESTClientOptions() []option.ClientOption {
func (c *restClient) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", gax.GoVersion}, keyval...)
kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "rest", "UNKNOWN")
- c.xGoogHeaders = []string{"x-goog-api-client", gax.XGoogHeader(kv...)}
+ c.xGoogHeaders = []string{
+ "x-goog-api-client", gax.XGoogHeader(kv...),
+ }
}
// Close closes the connection to the API service. The user should invoke this when
@@ -1649,7 +1680,7 @@ func (c *executeStreamingSqlRESTClient) Trailer() metadata.MD {
func (c *executeStreamingSqlRESTClient) CloseSend() error {
// This is a no-op to fulfill the interface.
- return fmt.Errorf("this method is not implemented for a server-stream")
+ return errors.New("this method is not implemented for a server-stream")
}
func (c *executeStreamingSqlRESTClient) Context() context.Context {
@@ -1658,12 +1689,12 @@ func (c *executeStreamingSqlRESTClient) Context() context.Context {
func (c *executeStreamingSqlRESTClient) SendMsg(m interface{}) error {
// This is a no-op to fulfill the interface.
- return fmt.Errorf("this method is not implemented for a server-stream")
+ return errors.New("this method is not implemented for a server-stream")
}
func (c *executeStreamingSqlRESTClient) RecvMsg(m interface{}) error {
// This is a no-op to fulfill the interface.
- return fmt.Errorf("this method is not implemented, use Recv")
+ return errors.New("this method is not implemented, use Recv")
}
// ExecuteBatchDml executes a batch of SQL DML statements. This method allows many statements
@@ -1915,7 +1946,7 @@ func (c *streamingReadRESTClient) Trailer() metadata.MD {
func (c *streamingReadRESTClient) CloseSend() error {
// This is a no-op to fulfill the interface.
- return fmt.Errorf("this method is not implemented for a server-stream")
+ return errors.New("this method is not implemented for a server-stream")
}
func (c *streamingReadRESTClient) Context() context.Context {
@@ -1924,12 +1955,12 @@ func (c *streamingReadRESTClient) Context() context.Context {
func (c *streamingReadRESTClient) SendMsg(m interface{}) error {
// This is a no-op to fulfill the interface.
- return fmt.Errorf("this method is not implemented for a server-stream")
+ return errors.New("this method is not implemented for a server-stream")
}
func (c *streamingReadRESTClient) RecvMsg(m interface{}) error {
// This is a no-op to fulfill the interface.
- return fmt.Errorf("this method is not implemented, use Recv")
+ return errors.New("this method is not implemented, use Recv")
}
// BeginTransaction begins a new transaction. This step can often be skipped:
@@ -2396,7 +2427,7 @@ func (c *batchWriteRESTClient) Trailer() metadata.MD {
func (c *batchWriteRESTClient) CloseSend() error {
// This is a no-op to fulfill the interface.
- return fmt.Errorf("this method is not implemented for a server-stream")
+ return errors.New("this method is not implemented for a server-stream")
}
func (c *batchWriteRESTClient) Context() context.Context {
@@ -2405,10 +2436,10 @@ func (c *batchWriteRESTClient) Context() context.Context {
func (c *batchWriteRESTClient) SendMsg(m interface{}) error {
// This is a no-op to fulfill the interface.
- return fmt.Errorf("this method is not implemented for a server-stream")
+ return errors.New("this method is not implemented for a server-stream")
}
func (c *batchWriteRESTClient) RecvMsg(m interface{}) error {
// This is a no-op to fulfill the interface.
- return fmt.Errorf("this method is not implemented, use Recv")
+ return errors.New("this method is not implemented, use Recv")
}
diff --git a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/commit_response.pb.go b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/commit_response.pb.go
index f038031f3..ccfb44258 100644
--- a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/commit_response.pb.go
+++ b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/commit_response.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2022 Google LLC
+// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.32.0
-// protoc v4.25.2
+// protoc-gen-go v1.34.2
+// protoc v4.25.3
// source: google/spanner/v1/commit_response.proto
package spannerpb
@@ -201,7 +201,7 @@ func file_google_spanner_v1_commit_response_proto_rawDescGZIP() []byte {
}
var file_google_spanner_v1_commit_response_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
-var file_google_spanner_v1_commit_response_proto_goTypes = []interface{}{
+var file_google_spanner_v1_commit_response_proto_goTypes = []any{
(*CommitResponse)(nil), // 0: google.spanner.v1.CommitResponse
(*CommitResponse_CommitStats)(nil), // 1: google.spanner.v1.CommitResponse.CommitStats
(*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp
@@ -222,7 +222,7 @@ func file_google_spanner_v1_commit_response_proto_init() {
return
}
if !protoimpl.UnsafeEnabled {
- file_google_spanner_v1_commit_response_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_commit_response_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*CommitResponse); i {
case 0:
return &v.state
@@ -234,7 +234,7 @@ func file_google_spanner_v1_commit_response_proto_init() {
return nil
}
}
- file_google_spanner_v1_commit_response_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_commit_response_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*CommitResponse_CommitStats); i {
case 0:
return &v.state
diff --git a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/keys.pb.go b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/keys.pb.go
index 84444aefb..0cfb01a43 100644
--- a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/keys.pb.go
+++ b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/keys.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2022 Google LLC
+// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.32.0
-// protoc v4.25.2
+// protoc-gen-go v1.34.2
+// protoc v4.25.3
// source: google/spanner/v1/keys.proto
package spannerpb
@@ -399,7 +399,7 @@ func file_google_spanner_v1_keys_proto_rawDescGZIP() []byte {
}
var file_google_spanner_v1_keys_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
-var file_google_spanner_v1_keys_proto_goTypes = []interface{}{
+var file_google_spanner_v1_keys_proto_goTypes = []any{
(*KeyRange)(nil), // 0: google.spanner.v1.KeyRange
(*KeySet)(nil), // 1: google.spanner.v1.KeySet
(*structpb.ListValue)(nil), // 2: google.protobuf.ListValue
@@ -424,7 +424,7 @@ func file_google_spanner_v1_keys_proto_init() {
return
}
if !protoimpl.UnsafeEnabled {
- file_google_spanner_v1_keys_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_keys_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*KeyRange); i {
case 0:
return &v.state
@@ -436,7 +436,7 @@ func file_google_spanner_v1_keys_proto_init() {
return nil
}
}
- file_google_spanner_v1_keys_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_keys_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*KeySet); i {
case 0:
return &v.state
@@ -449,7 +449,7 @@ func file_google_spanner_v1_keys_proto_init() {
}
}
}
- file_google_spanner_v1_keys_proto_msgTypes[0].OneofWrappers = []interface{}{
+ file_google_spanner_v1_keys_proto_msgTypes[0].OneofWrappers = []any{
(*KeyRange_StartClosed)(nil),
(*KeyRange_StartOpen)(nil),
(*KeyRange_EndClosed)(nil),
diff --git a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/mutation.pb.go b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/mutation.pb.go
index 533114d3a..bdbbac372 100644
--- a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/mutation.pb.go
+++ b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/mutation.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2022 Google LLC
+// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.32.0
-// protoc v4.25.2
+// protoc-gen-go v1.34.2
+// protoc v4.25.3
// source: google/spanner/v1/mutation.proto
package spannerpb
@@ -403,7 +403,7 @@ func file_google_spanner_v1_mutation_proto_rawDescGZIP() []byte {
}
var file_google_spanner_v1_mutation_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_google_spanner_v1_mutation_proto_goTypes = []interface{}{
+var file_google_spanner_v1_mutation_proto_goTypes = []any{
(*Mutation)(nil), // 0: google.spanner.v1.Mutation
(*Mutation_Write)(nil), // 1: google.spanner.v1.Mutation.Write
(*Mutation_Delete)(nil), // 2: google.spanner.v1.Mutation.Delete
@@ -432,7 +432,7 @@ func file_google_spanner_v1_mutation_proto_init() {
}
file_google_spanner_v1_keys_proto_init()
if !protoimpl.UnsafeEnabled {
- file_google_spanner_v1_mutation_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_mutation_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*Mutation); i {
case 0:
return &v.state
@@ -444,7 +444,7 @@ func file_google_spanner_v1_mutation_proto_init() {
return nil
}
}
- file_google_spanner_v1_mutation_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_mutation_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*Mutation_Write); i {
case 0:
return &v.state
@@ -456,7 +456,7 @@ func file_google_spanner_v1_mutation_proto_init() {
return nil
}
}
- file_google_spanner_v1_mutation_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_mutation_proto_msgTypes[2].Exporter = func(v any, i int) any {
switch v := v.(*Mutation_Delete); i {
case 0:
return &v.state
@@ -469,7 +469,7 @@ func file_google_spanner_v1_mutation_proto_init() {
}
}
}
- file_google_spanner_v1_mutation_proto_msgTypes[0].OneofWrappers = []interface{}{
+ file_google_spanner_v1_mutation_proto_msgTypes[0].OneofWrappers = []any{
(*Mutation_Insert)(nil),
(*Mutation_Update)(nil),
(*Mutation_InsertOrUpdate)(nil),
diff --git a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/query_plan.pb.go b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/query_plan.pb.go
index 6054ee59c..fe4411080 100644
--- a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/query_plan.pb.go
+++ b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/query_plan.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2022 Google LLC
+// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.32.0
-// protoc v4.25.2
+// protoc-gen-go v1.34.2
+// protoc v4.25.3
// source: google/spanner/v1/query_plan.proto
package spannerpb
@@ -494,7 +494,7 @@ func file_google_spanner_v1_query_plan_proto_rawDescGZIP() []byte {
var file_google_spanner_v1_query_plan_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_google_spanner_v1_query_plan_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
-var file_google_spanner_v1_query_plan_proto_goTypes = []interface{}{
+var file_google_spanner_v1_query_plan_proto_goTypes = []any{
(PlanNode_Kind)(0), // 0: google.spanner.v1.PlanNode.Kind
(*PlanNode)(nil), // 1: google.spanner.v1.PlanNode
(*QueryPlan)(nil), // 2: google.spanner.v1.QueryPlan
@@ -524,7 +524,7 @@ func file_google_spanner_v1_query_plan_proto_init() {
return
}
if !protoimpl.UnsafeEnabled {
- file_google_spanner_v1_query_plan_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_query_plan_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*PlanNode); i {
case 0:
return &v.state
@@ -536,7 +536,7 @@ func file_google_spanner_v1_query_plan_proto_init() {
return nil
}
}
- file_google_spanner_v1_query_plan_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_query_plan_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*QueryPlan); i {
case 0:
return &v.state
@@ -548,7 +548,7 @@ func file_google_spanner_v1_query_plan_proto_init() {
return nil
}
}
- file_google_spanner_v1_query_plan_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_query_plan_proto_msgTypes[2].Exporter = func(v any, i int) any {
switch v := v.(*PlanNode_ChildLink); i {
case 0:
return &v.state
@@ -560,7 +560,7 @@ func file_google_spanner_v1_query_plan_proto_init() {
return nil
}
}
- file_google_spanner_v1_query_plan_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_query_plan_proto_msgTypes[3].Exporter = func(v any, i int) any {
switch v := v.(*PlanNode_ShortRepresentation); i {
case 0:
return &v.state
diff --git a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/result_set.pb.go b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/result_set.pb.go
index 1f6ca2783..57b2cb401 100644
--- a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/result_set.pb.go
+++ b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/result_set.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2022 Google LLC
+// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.32.0
-// protoc v4.25.2
+// protoc-gen-go v1.34.2
+// protoc v4.25.3
// source: google/spanner/v1/result_set.proto
package spannerpb
@@ -584,7 +584,7 @@ func file_google_spanner_v1_result_set_proto_rawDescGZIP() []byte {
}
var file_google_spanner_v1_result_set_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
-var file_google_spanner_v1_result_set_proto_goTypes = []interface{}{
+var file_google_spanner_v1_result_set_proto_goTypes = []any{
(*ResultSet)(nil), // 0: google.spanner.v1.ResultSet
(*PartialResultSet)(nil), // 1: google.spanner.v1.PartialResultSet
(*ResultSetMetadata)(nil), // 2: google.spanner.v1.ResultSetMetadata
@@ -624,7 +624,7 @@ func file_google_spanner_v1_result_set_proto_init() {
file_google_spanner_v1_transaction_proto_init()
file_google_spanner_v1_type_proto_init()
if !protoimpl.UnsafeEnabled {
- file_google_spanner_v1_result_set_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_result_set_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*ResultSet); i {
case 0:
return &v.state
@@ -636,7 +636,7 @@ func file_google_spanner_v1_result_set_proto_init() {
return nil
}
}
- file_google_spanner_v1_result_set_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_result_set_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*PartialResultSet); i {
case 0:
return &v.state
@@ -648,7 +648,7 @@ func file_google_spanner_v1_result_set_proto_init() {
return nil
}
}
- file_google_spanner_v1_result_set_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_result_set_proto_msgTypes[2].Exporter = func(v any, i int) any {
switch v := v.(*ResultSetMetadata); i {
case 0:
return &v.state
@@ -660,7 +660,7 @@ func file_google_spanner_v1_result_set_proto_init() {
return nil
}
}
- file_google_spanner_v1_result_set_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_result_set_proto_msgTypes[3].Exporter = func(v any, i int) any {
switch v := v.(*ResultSetStats); i {
case 0:
return &v.state
@@ -673,7 +673,7 @@ func file_google_spanner_v1_result_set_proto_init() {
}
}
}
- file_google_spanner_v1_result_set_proto_msgTypes[3].OneofWrappers = []interface{}{
+ file_google_spanner_v1_result_set_proto_msgTypes[3].OneofWrappers = []any{
(*ResultSetStats_RowCountExact)(nil),
(*ResultSetStats_RowCountLowerBound)(nil),
}
diff --git a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/spanner.pb.go b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/spanner.pb.go
index c4f656d33..6831ecbc7 100644
--- a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/spanner.pb.go
+++ b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/spanner.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2023 Google LLC
+// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.32.0
-// protoc v4.25.2
+// protoc-gen-go v1.34.2
+// protoc v4.25.3
// source: google/spanner/v1/spanner.proto
package spannerpb
@@ -225,6 +225,153 @@ func (ExecuteSqlRequest_QueryMode) EnumDescriptor() ([]byte, []int) {
return file_google_spanner_v1_spanner_proto_rawDescGZIP(), []int{10, 0}
}
+// An option to control the order in which rows are returned from a read.
+type ReadRequest_OrderBy int32
+
+const (
+ // Default value.
+ //
+ // ORDER_BY_UNSPECIFIED is equivalent to ORDER_BY_PRIMARY_KEY.
+ ReadRequest_ORDER_BY_UNSPECIFIED ReadRequest_OrderBy = 0
+ // Read rows are returned in primary key order.
+ //
+ // In the event that this option is used in conjunction with the
+ // `partition_token` field, the API will return an `INVALID_ARGUMENT` error.
+ ReadRequest_ORDER_BY_PRIMARY_KEY ReadRequest_OrderBy = 1
+ // Read rows are returned in any order.
+ ReadRequest_ORDER_BY_NO_ORDER ReadRequest_OrderBy = 2
+)
+
+// Enum value maps for ReadRequest_OrderBy.
+var (
+ ReadRequest_OrderBy_name = map[int32]string{
+ 0: "ORDER_BY_UNSPECIFIED",
+ 1: "ORDER_BY_PRIMARY_KEY",
+ 2: "ORDER_BY_NO_ORDER",
+ }
+ ReadRequest_OrderBy_value = map[string]int32{
+ "ORDER_BY_UNSPECIFIED": 0,
+ "ORDER_BY_PRIMARY_KEY": 1,
+ "ORDER_BY_NO_ORDER": 2,
+ }
+)
+
+func (x ReadRequest_OrderBy) Enum() *ReadRequest_OrderBy {
+ p := new(ReadRequest_OrderBy)
+ *p = x
+ return p
+}
+
+func (x ReadRequest_OrderBy) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ReadRequest_OrderBy) Descriptor() protoreflect.EnumDescriptor {
+ return file_google_spanner_v1_spanner_proto_enumTypes[3].Descriptor()
+}
+
+func (ReadRequest_OrderBy) Type() protoreflect.EnumType {
+ return &file_google_spanner_v1_spanner_proto_enumTypes[3]
+}
+
+func (x ReadRequest_OrderBy) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ReadRequest_OrderBy.Descriptor instead.
+func (ReadRequest_OrderBy) EnumDescriptor() ([]byte, []int) {
+ return file_google_spanner_v1_spanner_proto_rawDescGZIP(), []int{18, 0}
+}
+
+// A lock hint mechanism for reads done within a transaction.
+type ReadRequest_LockHint int32
+
+const (
+ // Default value.
+ //
+ // LOCK_HINT_UNSPECIFIED is equivalent to LOCK_HINT_SHARED.
+ ReadRequest_LOCK_HINT_UNSPECIFIED ReadRequest_LockHint = 0
+ // Acquire shared locks.
+ //
+ // By default when you perform a read as part of a read-write transaction,
+ // Spanner acquires shared read locks, which allows other reads to still
+ // access the data until your transaction is ready to commit. When your
+ // transaction is committing and writes are being applied, the transaction
+ // attempts to upgrade to an exclusive lock for any data you are writing.
+ // For more information about locks, see [Lock
+ // modes](https://cloud.google.com/spanner/docs/introspection/lock-statistics#explain-lock-modes).
+ ReadRequest_LOCK_HINT_SHARED ReadRequest_LockHint = 1
+ // Acquire exclusive locks.
+ //
+ // Requesting exclusive locks is beneficial if you observe high write
+ // contention, which means you notice that multiple transactions are
+ // concurrently trying to read and write to the same data, resulting in a
+ // large number of aborts. This problem occurs when two transactions
+ // initially acquire shared locks and then both try to upgrade to exclusive
+ // locks at the same time. In this situation both transactions are waiting
+ // for the other to give up their lock, resulting in a deadlocked situation.
+ // Spanner is able to detect this occurring and force one of the
+ // transactions to abort. However, this is a slow and expensive operation
+ // and results in lower performance. In this case it makes sense to acquire
+ // exclusive locks at the start of the transaction because then when
+ // multiple transactions try to act on the same data, they automatically get
+ // serialized. Each transaction waits its turn to acquire the lock and
+ // avoids getting into deadlock situations.
+ //
+ // Because the exclusive lock hint is just a hint, it should not be
+ // considered equivalent to a mutex. In other words, you should not use
+ // Spanner exclusive locks as a mutual exclusion mechanism for the execution
+ // of code outside of Spanner.
+ //
+ // **Note:** Request exclusive locks judiciously because they block others
+ // from reading that data for the entire transaction, rather than just when
+ // the writes are being performed. Unless you observe high write contention,
+ // you should use the default of shared read locks so you don't prematurely
+ // block other clients from reading the data that you're writing to.
+ ReadRequest_LOCK_HINT_EXCLUSIVE ReadRequest_LockHint = 2
+)
+
+// Enum value maps for ReadRequest_LockHint.
+var (
+ ReadRequest_LockHint_name = map[int32]string{
+ 0: "LOCK_HINT_UNSPECIFIED",
+ 1: "LOCK_HINT_SHARED",
+ 2: "LOCK_HINT_EXCLUSIVE",
+ }
+ ReadRequest_LockHint_value = map[string]int32{
+ "LOCK_HINT_UNSPECIFIED": 0,
+ "LOCK_HINT_SHARED": 1,
+ "LOCK_HINT_EXCLUSIVE": 2,
+ }
+)
+
+func (x ReadRequest_LockHint) Enum() *ReadRequest_LockHint {
+ p := new(ReadRequest_LockHint)
+ *p = x
+ return p
+}
+
+func (x ReadRequest_LockHint) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ReadRequest_LockHint) Descriptor() protoreflect.EnumDescriptor {
+ return file_google_spanner_v1_spanner_proto_enumTypes[4].Descriptor()
+}
+
+func (ReadRequest_LockHint) Type() protoreflect.EnumType {
+ return &file_google_spanner_v1_spanner_proto_enumTypes[4]
+}
+
+func (x ReadRequest_LockHint) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ReadRequest_LockHint.Descriptor instead.
+func (ReadRequest_LockHint) EnumDescriptor() ([]byte, []int) {
+ return file_google_spanner_v1_spanner_proto_rawDescGZIP(), []int{18, 1}
+}
+
// The request for [CreateSession][google.spanner.v1.Spanner.CreateSession].
type CreateSessionRequest struct {
state protoimpl.MessageState
@@ -1851,6 +1998,17 @@ type ReadRequest struct {
// If the field is set to `true` but the request does not set
// `partition_token`, the API returns an `INVALID_ARGUMENT` error.
DataBoostEnabled bool `protobuf:"varint,15,opt,name=data_boost_enabled,json=dataBoostEnabled,proto3" json:"data_boost_enabled,omitempty"`
+ // Optional. Order for the returned rows.
+ //
+ // By default, Spanner will return result rows in primary key order except for
+ // PartitionRead requests. For applications that do not require rows to be
+ // returned in primary key (`ORDER_BY_PRIMARY_KEY`) order, setting
+ // `ORDER_BY_NO_ORDER` option allows Spanner to optimize row retrieval,
+ // resulting in lower latencies in certain cases (e.g. bulk point lookups).
+ OrderBy ReadRequest_OrderBy `protobuf:"varint,16,opt,name=order_by,json=orderBy,proto3,enum=google.spanner.v1.ReadRequest_OrderBy" json:"order_by,omitempty"`
+ // Optional. Lock Hint for the request, it can only be used with read-write
+ // transactions.
+ LockHint ReadRequest_LockHint `protobuf:"varint,17,opt,name=lock_hint,json=lockHint,proto3,enum=google.spanner.v1.ReadRequest_LockHint" json:"lock_hint,omitempty"`
}
func (x *ReadRequest) Reset() {
@@ -1969,6 +2127,20 @@ func (x *ReadRequest) GetDataBoostEnabled() bool {
return false
}
+func (x *ReadRequest) GetOrderBy() ReadRequest_OrderBy {
+ if x != nil {
+ return x.OrderBy
+ }
+ return ReadRequest_ORDER_BY_UNSPECIFIED
+}
+
+func (x *ReadRequest) GetLockHint() ReadRequest_LockHint {
+ if x != nil {
+ return x.LockHint
+ }
+ return ReadRequest_LOCK_HINT_UNSPECIFIED
+}
+
// The request for
// [BeginTransaction][google.spanner.v1.Spanner.BeginTransaction].
type BeginTransactionRequest struct {
@@ -3204,7 +3376,7 @@ var file_google_spanner_v1_spanner_proto_rawDesc = []byte{
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70,
0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x22, 0xda, 0x04, 0x0a, 0x0b, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x6e, 0x22, 0x99, 0x07, 0x0a, 0x0b, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x40, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x42, 0x26, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x20, 0x0a, 0x1e, 0x73, 0x70, 0x61, 0x6e,
0x6e, 0x65, 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63,
@@ -3241,308 +3413,328 @@ var file_google_spanner_v1_spanner_proto_rawDesc = []byte{
0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x12, 0x2c, 0x0a, 0x12, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x5f, 0x65,
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x64, 0x61,
- 0x74, 0x61, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xed,
- 0x01, 0x0a, 0x17, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x07, 0x73, 0x65,
- 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x26, 0xe0, 0x41, 0x02,
- 0xfa, 0x41, 0x20, 0x0a, 0x1e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x67, 0x6f, 0x6f,
- 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x65, 0x73, 0x73,
- 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x07,
- 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76,
- 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x12, 0x4a, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6f, 0x70,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f,
- 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0e,
- 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe9,
- 0x03, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x74, 0x61, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x46,
+ 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0e,
+ 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65,
+ 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f,
+ 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x49, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68,
+ 0x69, 0x6e, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65,
+ 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x48, 0x69,
+ 0x6e, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x69, 0x6e,
+ 0x74, 0x22, 0x54, 0x0a, 0x07, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x18, 0x0a, 0x14,
+ 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x42, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
+ 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f,
+ 0x42, 0x59, 0x5f, 0x50, 0x52, 0x49, 0x4d, 0x41, 0x52, 0x59, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01,
+ 0x12, 0x15, 0x0a, 0x11, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x42, 0x59, 0x5f, 0x4e, 0x4f, 0x5f,
+ 0x4f, 0x52, 0x44, 0x45, 0x52, 0x10, 0x02, 0x22, 0x54, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x6b, 0x48,
+ 0x69, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x15, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x48, 0x49, 0x4e, 0x54,
+ 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14,
+ 0x0a, 0x10, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x48, 0x49, 0x4e, 0x54, 0x5f, 0x53, 0x48, 0x41, 0x52,
+ 0x45, 0x44, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x48, 0x49, 0x4e,
+ 0x54, 0x5f, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x53, 0x49, 0x56, 0x45, 0x10, 0x02, 0x22, 0xed, 0x01,
+ 0x0a, 0x17, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x07, 0x73, 0x65, 0x73,
+ 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x26, 0xe0, 0x41, 0x02, 0xfa,
+ 0x41, 0x20, 0x0a, 0x1e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x65, 0x73, 0x73, 0x69,
+ 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x07, 0x6f,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31,
+ 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x12, 0x4a, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6f, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x6f,
+ 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0e, 0x72,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe9, 0x03,
+ 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+ 0x40, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x42, 0x26, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x20, 0x0a, 0x1e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65,
+ 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
+ 0x6e, 0x12, 0x27, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x74, 0x72, 0x61,
+ 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x5d, 0x0a, 0x16, 0x73, 0x69,
+ 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f,
+ 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54,
+ 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x48, 0x00, 0x52, 0x14, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x55, 0x73, 0x65, 0x54, 0x72,
+ 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x09, 0x6d, 0x75, 0x74,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31,
+ 0x2e, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6d, 0x75, 0x74, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x63,
+ 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x11, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53,
+ 0x74, 0x61, 0x74, 0x73, 0x12, 0x48, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x69, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0e,
+ 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x4a,
+ 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0e, 0x72, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x0d, 0x0a, 0x0b, 0x74, 0x72,
+ 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7f, 0x0a, 0x0f, 0x52, 0x6f, 0x6c,
+ 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x07,
+ 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x26, 0xe0,
+ 0x41, 0x02, 0xfa, 0x41, 0x20, 0x0a, 0x1e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a,
+ 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0d, 0x74, 0x72, 0x61,
+ 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x9f, 0x03, 0x0a, 0x11, 0x42,
+ 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x40, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x42, 0x26, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x20, 0x0a, 0x1e, 0x73, 0x70, 0x61, 0x6e, 0x6e,
0x65, 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69,
- 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x74, 0x72,
- 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x5d, 0x0a, 0x16, 0x73,
- 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x6e, 0x12, 0x4a, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6f, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
- 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x48, 0x00, 0x52, 0x14, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x55, 0x73, 0x65, 0x54,
- 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x09, 0x6d, 0x75,
- 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76,
- 0x31, 0x2e, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6d, 0x75, 0x74, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f,
- 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x11, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
- 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x48, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6d,
- 0x6d, 0x69, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
- 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52,
- 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12,
- 0x4a, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0e, 0x72, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x0d, 0x0a, 0x0b, 0x74,
- 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7f, 0x0a, 0x0f, 0x52, 0x6f,
- 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a,
- 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x26,
- 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x20, 0x0a, 0x1e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53,
- 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12,
- 0x2a, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
- 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0d, 0x74, 0x72,
- 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x9f, 0x03, 0x0a, 0x11,
- 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x12, 0x40, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x42, 0x26, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x20, 0x0a, 0x1e, 0x73, 0x70, 0x61, 0x6e,
- 0x6e, 0x65, 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63,
- 0x6f, 0x6d, 0x2f, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73,
- 0x69, 0x6f, 0x6e, 0x12, 0x4a, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6f,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31,
- 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52,
- 0x0e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
- 0x60, 0x0a, 0x0f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x67, 0x72, 0x6f, 0x75,
- 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74,
- 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d,
- 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x03, 0xe0, 0x41,
- 0x02, 0x52, 0x0e, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70,
- 0x73, 0x12, 0x49, 0x0a, 0x1f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x78, 0x6e,
- 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x72,
- 0x65, 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52,
- 0x1b, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x78, 0x6e, 0x46, 0x72, 0x6f, 0x6d, 0x43,
- 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x1a, 0x4f, 0x0a, 0x0d,
- 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x3e, 0x0a,
- 0x09, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65,
- 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03, 0xe0,
- 0x41, 0x02, 0x52, 0x09, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa1, 0x01,
- 0x0a, 0x12, 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x18,
- 0x01, 0x20, 0x03, 0x28, 0x05, 0x52, 0x07, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x12, 0x2a,
- 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12,
- 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74,
- 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x45, 0x0a, 0x10, 0x63, 0x6f,
- 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
- 0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
- 0x70, 0x32, 0x8b, 0x18, 0x0a, 0x07, 0x53, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0xa6, 0x01,
- 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12,
- 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72,
- 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
- 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73,
- 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0xda, 0x41, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
- 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3f, 0x3a, 0x01, 0x2a, 0x22, 0x3a, 0x2f, 0x76, 0x31, 0x2f,
- 0x7b, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
- 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a,
- 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65,
- 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xe0, 0x01, 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, 0x68,
- 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2d,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0e,
+ 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x60,
+ 0x0a, 0x0f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70,
+ 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63,
+ 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x75,
+ 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02,
+ 0x52, 0x0e, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73,
+ 0x12, 0x49, 0x0a, 0x1f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x78, 0x6e, 0x5f,
+ 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x65,
+ 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x1b,
+ 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x78, 0x6e, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68,
+ 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x1a, 0x4f, 0x0a, 0x0d, 0x4d,
+ 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x3e, 0x0a, 0x09,
+ 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72,
+ 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03, 0xe0, 0x41,
+ 0x02, 0x52, 0x09, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa1, 0x01, 0x0a,
+ 0x12, 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x18, 0x01,
+ 0x20, 0x03, 0x28, 0x05, 0x52, 0x07, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x12, 0x2a, 0x0a,
+ 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e,
+ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x45, 0x0a, 0x10, 0x63, 0x6f, 0x6d,
+ 0x6d, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
+ 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
+ 0x32, 0x8b, 0x18, 0x0a, 0x07, 0x53, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0xa6, 0x01, 0x0a,
+ 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x27,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e,
- 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65,
- 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e,
+ 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73,
+ 0x69, 0x6f, 0x6e, 0x22, 0x50, 0xda, 0x41, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
+ 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3f, 0x3a, 0x01, 0x2a, 0x22, 0x3a, 0x2f, 0x76, 0x31, 0x2f, 0x7b,
+ 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+ 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f,
+ 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x73,
+ 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xe0, 0x01, 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43,
+ 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2d, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76,
0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73,
- 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6a, 0xda,
- 0x41, 0x16, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2c, 0x73, 0x65, 0x73, 0x73, 0x69,
- 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4b, 0x3a, 0x01,
- 0x2a, 0x22, 0x46, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
+ 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31,
+ 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73,
+ 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6a, 0xda, 0x41,
+ 0x16, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
+ 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4b, 0x3a, 0x01, 0x2a,
+ 0x22, 0x46, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3d,
+ 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61,
+ 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73,
+ 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x62, 0x61, 0x74,
+ 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74,
+ 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53,
+ 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
+ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76,
+ 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x47, 0xda, 0x41, 0x04, 0x6e, 0x61,
+ 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3a, 0x12, 0x38, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e,
+ 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69,
+ 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62,
+ 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f,
+ 0x2a, 0x7d, 0x12, 0xae, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69,
+ 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61,
+ 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73,
+ 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
+ 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0xda, 0x41, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
+ 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3c, 0x12, 0x3a, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x64, 0x61,
+ 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f,
+ 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61,
+ 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69,
+ 0x6f, 0x6e, 0x73, 0x12, 0x99, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73,
+ 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+ 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x47, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82,
+ 0xd3, 0xe4, 0x93, 0x02, 0x3a, 0x2a, 0x38, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65,
0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74,
0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
- 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x62, 0x61,
- 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x0a, 0x47, 0x65,
- 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
- 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a,
- 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e,
- 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x47, 0xda, 0x41, 0x04, 0x6e,
- 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3a, 0x12, 0x38, 0x2f, 0x76, 0x31, 0x2f, 0x7b,
- 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f,
- 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61,
- 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73,
- 0x2f, 0x2a, 0x7d, 0x12, 0xae, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73,
- 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70,
- 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73,
- 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31,
- 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0xda, 0x41, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61,
- 0x73, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3c, 0x12, 0x3a, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x64,
- 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73,
- 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64,
- 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x73, 0x73,
- 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x99, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53,
- 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
- 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
- 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
- 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x47, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65,
- 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3a, 0x2a, 0x38, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d,
- 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73,
- 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
- 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d,
- 0x12, 0xa3, 0x01, 0x0a, 0x0a, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x71, 0x6c, 0x12,
- 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72,
- 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x71, 0x6c, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73,
- 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
- 0x53, 0x65, 0x74, 0x22, 0x51, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4b, 0x3a, 0x01, 0x2a, 0x22, 0x46,
- 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f,
- 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
- 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f,
- 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x65, 0x78, 0x65, 0x63,
- 0x75, 0x74, 0x65, 0x53, 0x71, 0x6c, 0x12, 0xbe, 0x01, 0x0a, 0x13, 0x45, 0x78, 0x65, 0x63, 0x75,
- 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x71, 0x6c, 0x12, 0x24,
+ 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x12,
+ 0xa3, 0x01, 0x0a, 0x0a, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x71, 0x6c, 0x12, 0x24,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e,
0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x71, 0x6c, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70,
- 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c,
- 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x65, 0x74, 0x22, 0x5a, 0x82, 0xd3, 0xe4, 0x93, 0x02,
- 0x54, 0x3a, 0x01, 0x2a, 0x22, 0x4f, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69,
- 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e,
- 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61,
- 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a,
- 0x7d, 0x3a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69,
- 0x6e, 0x67, 0x53, 0x71, 0x6c, 0x30, 0x01, 0x12, 0xc0, 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63,
- 0x75, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x6d, 0x6c, 0x12, 0x29, 0x2e, 0x67, 0x6f,
- 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
- 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x6d, 0x6c, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75,
- 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x6d, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
- 0x73, 0x65, 0x22, 0x56, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x50, 0x3a, 0x01, 0x2a, 0x22, 0x4b, 0x2f,
+ 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70,
+ 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53,
+ 0x65, 0x74, 0x22, 0x51, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4b, 0x3a, 0x01, 0x2a, 0x22, 0x46, 0x2f,
0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a,
0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73,
0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73,
0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x65, 0x78, 0x65, 0x63, 0x75,
- 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x6d, 0x6c, 0x12, 0x91, 0x01, 0x0a, 0x04, 0x52,
- 0x65, 0x61, 0x64, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61,
- 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61,
- 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x65,
- 0x74, 0x22, 0x4b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x45, 0x3a, 0x01, 0x2a, 0x22, 0x40, 0x2f, 0x76,
+ 0x74, 0x65, 0x53, 0x71, 0x6c, 0x12, 0xbe, 0x01, 0x0a, 0x13, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
+ 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x71, 0x6c, 0x12, 0x24, 0x2e,
+ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76,
+ 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x71, 0x6c, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61,
+ 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x52,
+ 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x65, 0x74, 0x22, 0x5a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x54,
+ 0x3a, 0x01, 0x2a, 0x22, 0x4f, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
+ 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73,
+ 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
+ 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d,
+ 0x3a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e,
+ 0x67, 0x53, 0x71, 0x6c, 0x30, 0x01, 0x12, 0xc0, 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75,
+ 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x6d, 0x6c, 0x12, 0x29, 0x2e, 0x67, 0x6f, 0x6f,
+ 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45,
+ 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x6d, 0x6c, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73,
+ 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
+ 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x6d, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x22, 0x56, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x50, 0x3a, 0x01, 0x2a, 0x22, 0x4b, 0x2f, 0x76,
0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65,
0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f,
0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65,
- 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x72, 0x65, 0x61, 0x64, 0x12, 0xac,
- 0x01, 0x0a, 0x0d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64,
- 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65,
- 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
- 0x1a, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65,
- 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x75,
- 0x6c, 0x74, 0x53, 0x65, 0x74, 0x22, 0x54, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4e, 0x3a, 0x01, 0x2a,
- 0x22, 0x49, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70,
- 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
- 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f,
- 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x73, 0x74,
- 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x30, 0x01, 0x12, 0xc9, 0x01,
- 0x0a, 0x10, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x12, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e,
- 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x72, 0x61, 0x6e,
- 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e,
- 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e,
- 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x69,
- 0xda, 0x41, 0x0f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x6f, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x51, 0x3a, 0x01, 0x2a, 0x22, 0x4c, 0x2f, 0x76, 0x31,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74,
+ 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x6d, 0x6c, 0x12, 0x91, 0x01, 0x0a, 0x04, 0x52, 0x65,
+ 0x61, 0x64, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e,
+ 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e,
+ 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x65, 0x74,
+ 0x22, 0x4b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x45, 0x3a, 0x01, 0x2a, 0x22, 0x40, 0x2f, 0x76, 0x31,
0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a,
0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73,
- 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x72,
- 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0xeb, 0x01, 0x0a, 0x06, 0x43, 0x6f,
- 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x20, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70,
- 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69,
- 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0xda, 0x41, 0x20, 0x73,
- 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x2c, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xda,
- 0x41, 0x28, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65,
- 0x5f, 0x75, 0x73, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x2c, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x47,
- 0x3a, 0x01, 0x2a, 0x22, 0x42, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
+ 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x72, 0x65, 0x61, 0x64, 0x12, 0xac, 0x01,
+ 0x0a, 0x0d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x12,
+ 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72,
+ 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+ 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72,
+ 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x75, 0x6c,
+ 0x74, 0x53, 0x65, 0x74, 0x22, 0x54, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4e, 0x3a, 0x01, 0x2a, 0x22,
+ 0x49, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72,
+ 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
+ 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a,
+ 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x73, 0x74, 0x72,
+ 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x30, 0x01, 0x12, 0xc9, 0x01, 0x0a,
+ 0x10, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x12, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e,
+ 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73,
+ 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e,
+ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76,
+ 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x69, 0xda,
+ 0x41, 0x0f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x51, 0x3a, 0x01, 0x2a, 0x22, 0x4c, 0x2f, 0x76, 0x31, 0x2f,
+ 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74,
+ 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f,
+ 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73,
+ 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x72, 0x61,
+ 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0xeb, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6d,
+ 0x6d, 0x69, 0x74, 0x12, 0x20, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61,
+ 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73,
+ 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0xda, 0x41, 0x20, 0x73, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x5f, 0x69, 0x64, 0x2c, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xda, 0x41,
+ 0x28, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f,
+ 0x75, 0x73, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c,
+ 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x47, 0x3a,
+ 0x01, 0x2a, 0x22, 0x42, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+ 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74,
+ 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
+ 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0xb0, 0x01, 0x0a, 0x08, 0x52, 0x6f, 0x6c, 0x6c, 0x62,
+ 0x61, 0x63, 0x6b, 0x12, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61,
+ 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
+ 0x68, 0xda, 0x41, 0x16, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x74, 0x72, 0x61, 0x6e,
+ 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49,
+ 0x3a, 0x01, 0x2a, 0x22, 0x44, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73,
0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d,
- 0x3a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0xb0, 0x01, 0x0a, 0x08, 0x52, 0x6f, 0x6c, 0x6c,
- 0x62, 0x61, 0x63, 0x6b, 0x12, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70,
- 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63,
- 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
- 0x22, 0x68, 0xda, 0x41, 0x16, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x74, 0x72, 0x61,
- 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02,
- 0x49, 0x3a, 0x01, 0x2a, 0x22, 0x44, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69,
- 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e,
- 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61,
- 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a,
- 0x7d, 0x3a, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0xb7, 0x01, 0x0a, 0x0e, 0x50,
- 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x28, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76,
- 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74,
- 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x82,
- 0xd3, 0xe4, 0x93, 0x02, 0x4f, 0x3a, 0x01, 0x2a, 0x22, 0x4a, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73,
- 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f,
- 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61,
- 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
- 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x51,
- 0x75, 0x65, 0x72, 0x79, 0x12, 0xb4, 0x01, 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
- 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x12, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+ 0x3a, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0xb7, 0x01, 0x0a, 0x0e, 0x50, 0x61,
+ 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x28, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31,
+ 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69,
- 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
- 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72,
- 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4e, 0x3a, 0x01, 0x2a,
- 0x22, 0x49, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70,
- 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
- 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f,
- 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x70, 0x61,
- 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x12, 0xc8, 0x01, 0x0a, 0x0a,
- 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x24, 0x2e, 0x67, 0x6f, 0x6f,
- 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42,
- 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
- 0x1a, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65,
- 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, 0xda, 0x41, 0x17, 0x73, 0x65, 0x73, 0x73,
- 0x69, 0x6f, 0x6e, 0x2c, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x67, 0x72, 0x6f,
- 0x75, 0x70, 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4b, 0x3a, 0x01, 0x2a, 0x22, 0x46, 0x2f, 0x76,
- 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65,
- 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f,
- 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65,
- 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x57,
- 0x72, 0x69, 0x74, 0x65, 0x30, 0x01, 0x1a, 0x77, 0xca, 0x41, 0x16, 0x73, 0x70, 0x61, 0x6e, 0x6e,
- 0x65, 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f,
- 0x6d, 0xd2, 0x41, 0x5b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61,
- 0x75, 0x74, 0x68, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f,
- 0x72, 0x6d, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x82, 0xd3,
+ 0xe4, 0x93, 0x02, 0x4f, 0x3a, 0x01, 0x2a, 0x22, 0x4a, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a,
+ 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74,
+ 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+ 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75,
+ 0x65, 0x72, 0x79, 0x12, 0xb4, 0x01, 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f,
+ 0x6e, 0x52, 0x65, 0x61, 0x64, 0x12, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73,
+ 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74,
+ 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e,
+ 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4e, 0x3a, 0x01, 0x2a, 0x22,
+ 0x49, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72,
+ 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
+ 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a,
+ 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x70, 0x61, 0x72,
+ 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x64, 0x12, 0xc8, 0x01, 0x0a, 0x0a, 0x42,
+ 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61,
+ 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+ 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72,
+ 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, 0xda, 0x41, 0x17, 0x73, 0x65, 0x73, 0x73, 0x69,
+ 0x6f, 0x6e, 0x2c, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x67, 0x72, 0x6f, 0x75,
+ 0x70, 0x73, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4b, 0x3a, 0x01, 0x2a, 0x22, 0x46, 0x2f, 0x76, 0x31,
+ 0x2f, 0x7b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+ 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a,
+ 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x73,
+ 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72,
+ 0x69, 0x74, 0x65, 0x30, 0x01, 0x1a, 0x77, 0xca, 0x41, 0x16, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65,
+ 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d,
+ 0xd2, 0x41, 0x5b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75,
- 0x74, 0x68, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x42,
- 0x91, 0x02, 0xea, 0x41, 0x5f, 0x0a, 0x1f, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x61,
- 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x3c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73,
- 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61,
- 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x7d, 0x2f,
- 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x62,
- 0x61, 0x73, 0x65, 0x7d, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x53, 0x70, 0x61,
- 0x6e, 0x6e, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x63, 0x6c, 0x6f,
- 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f,
- 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2f, 0x73,
- 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x70, 0x62, 0x3b, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72,
- 0x70, 0x62, 0xaa, 0x02, 0x17, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75,
- 0x64, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x17, 0x47,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x53, 0x70, 0x61, 0x6e,
- 0x6e, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a,
- 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x53, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x3a,
- 0x3a, 0x56, 0x31, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x74, 0x68, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
+ 0x6d, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74,
+ 0x68, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x42, 0x91,
+ 0x02, 0xea, 0x41, 0x5f, 0x0a, 0x1f, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x61, 0x74,
+ 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x3c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f,
+ 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+ 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x7d, 0x2f, 0x64,
+ 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61,
+ 0x73, 0x65, 0x7d, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+ 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x53, 0x70, 0x61, 0x6e,
+ 0x6e, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x63, 0x6c, 0x6f, 0x75,
+ 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f,
+ 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2f, 0x73, 0x70,
+ 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x70, 0x62, 0x3b, 0x73, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x70,
+ 0x62, 0xaa, 0x02, 0x17, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64,
+ 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x17, 0x47, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x53, 0x70, 0x61, 0x6e, 0x6e,
+ 0x65, 0x72, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a,
+ 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x53, 0x70, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x3a, 0x3a,
+ 0x56, 0x31, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -3557,153 +3749,157 @@ func file_google_spanner_v1_spanner_proto_rawDescGZIP() []byte {
return file_google_spanner_v1_spanner_proto_rawDescData
}
-var file_google_spanner_v1_spanner_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
+var file_google_spanner_v1_spanner_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
var file_google_spanner_v1_spanner_proto_msgTypes = make([]protoimpl.MessageInfo, 34)
-var file_google_spanner_v1_spanner_proto_goTypes = []interface{}{
+var file_google_spanner_v1_spanner_proto_goTypes = []any{
(RequestOptions_Priority)(0), // 0: google.spanner.v1.RequestOptions.Priority
(DirectedReadOptions_ReplicaSelection_Type)(0), // 1: google.spanner.v1.DirectedReadOptions.ReplicaSelection.Type
(ExecuteSqlRequest_QueryMode)(0), // 2: google.spanner.v1.ExecuteSqlRequest.QueryMode
- (*CreateSessionRequest)(nil), // 3: google.spanner.v1.CreateSessionRequest
- (*BatchCreateSessionsRequest)(nil), // 4: google.spanner.v1.BatchCreateSessionsRequest
- (*BatchCreateSessionsResponse)(nil), // 5: google.spanner.v1.BatchCreateSessionsResponse
- (*Session)(nil), // 6: google.spanner.v1.Session
- (*GetSessionRequest)(nil), // 7: google.spanner.v1.GetSessionRequest
- (*ListSessionsRequest)(nil), // 8: google.spanner.v1.ListSessionsRequest
- (*ListSessionsResponse)(nil), // 9: google.spanner.v1.ListSessionsResponse
- (*DeleteSessionRequest)(nil), // 10: google.spanner.v1.DeleteSessionRequest
- (*RequestOptions)(nil), // 11: google.spanner.v1.RequestOptions
- (*DirectedReadOptions)(nil), // 12: google.spanner.v1.DirectedReadOptions
- (*ExecuteSqlRequest)(nil), // 13: google.spanner.v1.ExecuteSqlRequest
- (*ExecuteBatchDmlRequest)(nil), // 14: google.spanner.v1.ExecuteBatchDmlRequest
- (*ExecuteBatchDmlResponse)(nil), // 15: google.spanner.v1.ExecuteBatchDmlResponse
- (*PartitionOptions)(nil), // 16: google.spanner.v1.PartitionOptions
- (*PartitionQueryRequest)(nil), // 17: google.spanner.v1.PartitionQueryRequest
- (*PartitionReadRequest)(nil), // 18: google.spanner.v1.PartitionReadRequest
- (*Partition)(nil), // 19: google.spanner.v1.Partition
- (*PartitionResponse)(nil), // 20: google.spanner.v1.PartitionResponse
- (*ReadRequest)(nil), // 21: google.spanner.v1.ReadRequest
- (*BeginTransactionRequest)(nil), // 22: google.spanner.v1.BeginTransactionRequest
- (*CommitRequest)(nil), // 23: google.spanner.v1.CommitRequest
- (*RollbackRequest)(nil), // 24: google.spanner.v1.RollbackRequest
- (*BatchWriteRequest)(nil), // 25: google.spanner.v1.BatchWriteRequest
- (*BatchWriteResponse)(nil), // 26: google.spanner.v1.BatchWriteResponse
- nil, // 27: google.spanner.v1.Session.LabelsEntry
- (*DirectedReadOptions_ReplicaSelection)(nil), // 28: google.spanner.v1.DirectedReadOptions.ReplicaSelection
- (*DirectedReadOptions_IncludeReplicas)(nil), // 29: google.spanner.v1.DirectedReadOptions.IncludeReplicas
- (*DirectedReadOptions_ExcludeReplicas)(nil), // 30: google.spanner.v1.DirectedReadOptions.ExcludeReplicas
- (*ExecuteSqlRequest_QueryOptions)(nil), // 31: google.spanner.v1.ExecuteSqlRequest.QueryOptions
- nil, // 32: google.spanner.v1.ExecuteSqlRequest.ParamTypesEntry
- (*ExecuteBatchDmlRequest_Statement)(nil), // 33: google.spanner.v1.ExecuteBatchDmlRequest.Statement
- nil, // 34: google.spanner.v1.ExecuteBatchDmlRequest.Statement.ParamTypesEntry
- nil, // 35: google.spanner.v1.PartitionQueryRequest.ParamTypesEntry
- (*BatchWriteRequest_MutationGroup)(nil), // 36: google.spanner.v1.BatchWriteRequest.MutationGroup
- (*timestamppb.Timestamp)(nil), // 37: google.protobuf.Timestamp
- (*TransactionSelector)(nil), // 38: google.spanner.v1.TransactionSelector
- (*structpb.Struct)(nil), // 39: google.protobuf.Struct
- (*ResultSet)(nil), // 40: google.spanner.v1.ResultSet
- (*status.Status)(nil), // 41: google.rpc.Status
- (*KeySet)(nil), // 42: google.spanner.v1.KeySet
- (*Transaction)(nil), // 43: google.spanner.v1.Transaction
- (*TransactionOptions)(nil), // 44: google.spanner.v1.TransactionOptions
- (*Mutation)(nil), // 45: google.spanner.v1.Mutation
- (*durationpb.Duration)(nil), // 46: google.protobuf.Duration
- (*Type)(nil), // 47: google.spanner.v1.Type
- (*emptypb.Empty)(nil), // 48: google.protobuf.Empty
- (*PartialResultSet)(nil), // 49: google.spanner.v1.PartialResultSet
- (*CommitResponse)(nil), // 50: google.spanner.v1.CommitResponse
+ (ReadRequest_OrderBy)(0), // 3: google.spanner.v1.ReadRequest.OrderBy
+ (ReadRequest_LockHint)(0), // 4: google.spanner.v1.ReadRequest.LockHint
+ (*CreateSessionRequest)(nil), // 5: google.spanner.v1.CreateSessionRequest
+ (*BatchCreateSessionsRequest)(nil), // 6: google.spanner.v1.BatchCreateSessionsRequest
+ (*BatchCreateSessionsResponse)(nil), // 7: google.spanner.v1.BatchCreateSessionsResponse
+ (*Session)(nil), // 8: google.spanner.v1.Session
+ (*GetSessionRequest)(nil), // 9: google.spanner.v1.GetSessionRequest
+ (*ListSessionsRequest)(nil), // 10: google.spanner.v1.ListSessionsRequest
+ (*ListSessionsResponse)(nil), // 11: google.spanner.v1.ListSessionsResponse
+ (*DeleteSessionRequest)(nil), // 12: google.spanner.v1.DeleteSessionRequest
+ (*RequestOptions)(nil), // 13: google.spanner.v1.RequestOptions
+ (*DirectedReadOptions)(nil), // 14: google.spanner.v1.DirectedReadOptions
+ (*ExecuteSqlRequest)(nil), // 15: google.spanner.v1.ExecuteSqlRequest
+ (*ExecuteBatchDmlRequest)(nil), // 16: google.spanner.v1.ExecuteBatchDmlRequest
+ (*ExecuteBatchDmlResponse)(nil), // 17: google.spanner.v1.ExecuteBatchDmlResponse
+ (*PartitionOptions)(nil), // 18: google.spanner.v1.PartitionOptions
+ (*PartitionQueryRequest)(nil), // 19: google.spanner.v1.PartitionQueryRequest
+ (*PartitionReadRequest)(nil), // 20: google.spanner.v1.PartitionReadRequest
+ (*Partition)(nil), // 21: google.spanner.v1.Partition
+ (*PartitionResponse)(nil), // 22: google.spanner.v1.PartitionResponse
+ (*ReadRequest)(nil), // 23: google.spanner.v1.ReadRequest
+ (*BeginTransactionRequest)(nil), // 24: google.spanner.v1.BeginTransactionRequest
+ (*CommitRequest)(nil), // 25: google.spanner.v1.CommitRequest
+ (*RollbackRequest)(nil), // 26: google.spanner.v1.RollbackRequest
+ (*BatchWriteRequest)(nil), // 27: google.spanner.v1.BatchWriteRequest
+ (*BatchWriteResponse)(nil), // 28: google.spanner.v1.BatchWriteResponse
+ nil, // 29: google.spanner.v1.Session.LabelsEntry
+ (*DirectedReadOptions_ReplicaSelection)(nil), // 30: google.spanner.v1.DirectedReadOptions.ReplicaSelection
+ (*DirectedReadOptions_IncludeReplicas)(nil), // 31: google.spanner.v1.DirectedReadOptions.IncludeReplicas
+ (*DirectedReadOptions_ExcludeReplicas)(nil), // 32: google.spanner.v1.DirectedReadOptions.ExcludeReplicas
+ (*ExecuteSqlRequest_QueryOptions)(nil), // 33: google.spanner.v1.ExecuteSqlRequest.QueryOptions
+ nil, // 34: google.spanner.v1.ExecuteSqlRequest.ParamTypesEntry
+ (*ExecuteBatchDmlRequest_Statement)(nil), // 35: google.spanner.v1.ExecuteBatchDmlRequest.Statement
+ nil, // 36: google.spanner.v1.ExecuteBatchDmlRequest.Statement.ParamTypesEntry
+ nil, // 37: google.spanner.v1.PartitionQueryRequest.ParamTypesEntry
+ (*BatchWriteRequest_MutationGroup)(nil), // 38: google.spanner.v1.BatchWriteRequest.MutationGroup
+ (*timestamppb.Timestamp)(nil), // 39: google.protobuf.Timestamp
+ (*TransactionSelector)(nil), // 40: google.spanner.v1.TransactionSelector
+ (*structpb.Struct)(nil), // 41: google.protobuf.Struct
+ (*ResultSet)(nil), // 42: google.spanner.v1.ResultSet
+ (*status.Status)(nil), // 43: google.rpc.Status
+ (*KeySet)(nil), // 44: google.spanner.v1.KeySet
+ (*Transaction)(nil), // 45: google.spanner.v1.Transaction
+ (*TransactionOptions)(nil), // 46: google.spanner.v1.TransactionOptions
+ (*Mutation)(nil), // 47: google.spanner.v1.Mutation
+ (*durationpb.Duration)(nil), // 48: google.protobuf.Duration
+ (*Type)(nil), // 49: google.spanner.v1.Type
+ (*emptypb.Empty)(nil), // 50: google.protobuf.Empty
+ (*PartialResultSet)(nil), // 51: google.spanner.v1.PartialResultSet
+ (*CommitResponse)(nil), // 52: google.spanner.v1.CommitResponse
}
var file_google_spanner_v1_spanner_proto_depIdxs = []int32{
- 6, // 0: google.spanner.v1.CreateSessionRequest.session:type_name -> google.spanner.v1.Session
- 6, // 1: google.spanner.v1.BatchCreateSessionsRequest.session_template:type_name -> google.spanner.v1.Session
- 6, // 2: google.spanner.v1.BatchCreateSessionsResponse.session:type_name -> google.spanner.v1.Session
- 27, // 3: google.spanner.v1.Session.labels:type_name -> google.spanner.v1.Session.LabelsEntry
- 37, // 4: google.spanner.v1.Session.create_time:type_name -> google.protobuf.Timestamp
- 37, // 5: google.spanner.v1.Session.approximate_last_use_time:type_name -> google.protobuf.Timestamp
- 6, // 6: google.spanner.v1.ListSessionsResponse.sessions:type_name -> google.spanner.v1.Session
+ 8, // 0: google.spanner.v1.CreateSessionRequest.session:type_name -> google.spanner.v1.Session
+ 8, // 1: google.spanner.v1.BatchCreateSessionsRequest.session_template:type_name -> google.spanner.v1.Session
+ 8, // 2: google.spanner.v1.BatchCreateSessionsResponse.session:type_name -> google.spanner.v1.Session
+ 29, // 3: google.spanner.v1.Session.labels:type_name -> google.spanner.v1.Session.LabelsEntry
+ 39, // 4: google.spanner.v1.Session.create_time:type_name -> google.protobuf.Timestamp
+ 39, // 5: google.spanner.v1.Session.approximate_last_use_time:type_name -> google.protobuf.Timestamp
+ 8, // 6: google.spanner.v1.ListSessionsResponse.sessions:type_name -> google.spanner.v1.Session
0, // 7: google.spanner.v1.RequestOptions.priority:type_name -> google.spanner.v1.RequestOptions.Priority
- 29, // 8: google.spanner.v1.DirectedReadOptions.include_replicas:type_name -> google.spanner.v1.DirectedReadOptions.IncludeReplicas
- 30, // 9: google.spanner.v1.DirectedReadOptions.exclude_replicas:type_name -> google.spanner.v1.DirectedReadOptions.ExcludeReplicas
- 38, // 10: google.spanner.v1.ExecuteSqlRequest.transaction:type_name -> google.spanner.v1.TransactionSelector
- 39, // 11: google.spanner.v1.ExecuteSqlRequest.params:type_name -> google.protobuf.Struct
- 32, // 12: google.spanner.v1.ExecuteSqlRequest.param_types:type_name -> google.spanner.v1.ExecuteSqlRequest.ParamTypesEntry
+ 31, // 8: google.spanner.v1.DirectedReadOptions.include_replicas:type_name -> google.spanner.v1.DirectedReadOptions.IncludeReplicas
+ 32, // 9: google.spanner.v1.DirectedReadOptions.exclude_replicas:type_name -> google.spanner.v1.DirectedReadOptions.ExcludeReplicas
+ 40, // 10: google.spanner.v1.ExecuteSqlRequest.transaction:type_name -> google.spanner.v1.TransactionSelector
+ 41, // 11: google.spanner.v1.ExecuteSqlRequest.params:type_name -> google.protobuf.Struct
+ 34, // 12: google.spanner.v1.ExecuteSqlRequest.param_types:type_name -> google.spanner.v1.ExecuteSqlRequest.ParamTypesEntry
2, // 13: google.spanner.v1.ExecuteSqlRequest.query_mode:type_name -> google.spanner.v1.ExecuteSqlRequest.QueryMode
- 31, // 14: google.spanner.v1.ExecuteSqlRequest.query_options:type_name -> google.spanner.v1.ExecuteSqlRequest.QueryOptions
- 11, // 15: google.spanner.v1.ExecuteSqlRequest.request_options:type_name -> google.spanner.v1.RequestOptions
- 12, // 16: google.spanner.v1.ExecuteSqlRequest.directed_read_options:type_name -> google.spanner.v1.DirectedReadOptions
- 38, // 17: google.spanner.v1.ExecuteBatchDmlRequest.transaction:type_name -> google.spanner.v1.TransactionSelector
- 33, // 18: google.spanner.v1.ExecuteBatchDmlRequest.statements:type_name -> google.spanner.v1.ExecuteBatchDmlRequest.Statement
- 11, // 19: google.spanner.v1.ExecuteBatchDmlRequest.request_options:type_name -> google.spanner.v1.RequestOptions
- 40, // 20: google.spanner.v1.ExecuteBatchDmlResponse.result_sets:type_name -> google.spanner.v1.ResultSet
- 41, // 21: google.spanner.v1.ExecuteBatchDmlResponse.status:type_name -> google.rpc.Status
- 38, // 22: google.spanner.v1.PartitionQueryRequest.transaction:type_name -> google.spanner.v1.TransactionSelector
- 39, // 23: google.spanner.v1.PartitionQueryRequest.params:type_name -> google.protobuf.Struct
- 35, // 24: google.spanner.v1.PartitionQueryRequest.param_types:type_name -> google.spanner.v1.PartitionQueryRequest.ParamTypesEntry
- 16, // 25: google.spanner.v1.PartitionQueryRequest.partition_options:type_name -> google.spanner.v1.PartitionOptions
- 38, // 26: google.spanner.v1.PartitionReadRequest.transaction:type_name -> google.spanner.v1.TransactionSelector
- 42, // 27: google.spanner.v1.PartitionReadRequest.key_set:type_name -> google.spanner.v1.KeySet
- 16, // 28: google.spanner.v1.PartitionReadRequest.partition_options:type_name -> google.spanner.v1.PartitionOptions
- 19, // 29: google.spanner.v1.PartitionResponse.partitions:type_name -> google.spanner.v1.Partition
- 43, // 30: google.spanner.v1.PartitionResponse.transaction:type_name -> google.spanner.v1.Transaction
- 38, // 31: google.spanner.v1.ReadRequest.transaction:type_name -> google.spanner.v1.TransactionSelector
- 42, // 32: google.spanner.v1.ReadRequest.key_set:type_name -> google.spanner.v1.KeySet
- 11, // 33: google.spanner.v1.ReadRequest.request_options:type_name -> google.spanner.v1.RequestOptions
- 12, // 34: google.spanner.v1.ReadRequest.directed_read_options:type_name -> google.spanner.v1.DirectedReadOptions
- 44, // 35: google.spanner.v1.BeginTransactionRequest.options:type_name -> google.spanner.v1.TransactionOptions
- 11, // 36: google.spanner.v1.BeginTransactionRequest.request_options:type_name -> google.spanner.v1.RequestOptions
- 44, // 37: google.spanner.v1.CommitRequest.single_use_transaction:type_name -> google.spanner.v1.TransactionOptions
- 45, // 38: google.spanner.v1.CommitRequest.mutations:type_name -> google.spanner.v1.Mutation
- 46, // 39: google.spanner.v1.CommitRequest.max_commit_delay:type_name -> google.protobuf.Duration
- 11, // 40: google.spanner.v1.CommitRequest.request_options:type_name -> google.spanner.v1.RequestOptions
- 11, // 41: google.spanner.v1.BatchWriteRequest.request_options:type_name -> google.spanner.v1.RequestOptions
- 36, // 42: google.spanner.v1.BatchWriteRequest.mutation_groups:type_name -> google.spanner.v1.BatchWriteRequest.MutationGroup
- 41, // 43: google.spanner.v1.BatchWriteResponse.status:type_name -> google.rpc.Status
- 37, // 44: google.spanner.v1.BatchWriteResponse.commit_timestamp:type_name -> google.protobuf.Timestamp
- 1, // 45: google.spanner.v1.DirectedReadOptions.ReplicaSelection.type:type_name -> google.spanner.v1.DirectedReadOptions.ReplicaSelection.Type
- 28, // 46: google.spanner.v1.DirectedReadOptions.IncludeReplicas.replica_selections:type_name -> google.spanner.v1.DirectedReadOptions.ReplicaSelection
- 28, // 47: google.spanner.v1.DirectedReadOptions.ExcludeReplicas.replica_selections:type_name -> google.spanner.v1.DirectedReadOptions.ReplicaSelection
- 47, // 48: google.spanner.v1.ExecuteSqlRequest.ParamTypesEntry.value:type_name -> google.spanner.v1.Type
- 39, // 49: google.spanner.v1.ExecuteBatchDmlRequest.Statement.params:type_name -> google.protobuf.Struct
- 34, // 50: google.spanner.v1.ExecuteBatchDmlRequest.Statement.param_types:type_name -> google.spanner.v1.ExecuteBatchDmlRequest.Statement.ParamTypesEntry
- 47, // 51: google.spanner.v1.ExecuteBatchDmlRequest.Statement.ParamTypesEntry.value:type_name -> google.spanner.v1.Type
- 47, // 52: google.spanner.v1.PartitionQueryRequest.ParamTypesEntry.value:type_name -> google.spanner.v1.Type
- 45, // 53: google.spanner.v1.BatchWriteRequest.MutationGroup.mutations:type_name -> google.spanner.v1.Mutation
- 3, // 54: google.spanner.v1.Spanner.CreateSession:input_type -> google.spanner.v1.CreateSessionRequest
- 4, // 55: google.spanner.v1.Spanner.BatchCreateSessions:input_type -> google.spanner.v1.BatchCreateSessionsRequest
- 7, // 56: google.spanner.v1.Spanner.GetSession:input_type -> google.spanner.v1.GetSessionRequest
- 8, // 57: google.spanner.v1.Spanner.ListSessions:input_type -> google.spanner.v1.ListSessionsRequest
- 10, // 58: google.spanner.v1.Spanner.DeleteSession:input_type -> google.spanner.v1.DeleteSessionRequest
- 13, // 59: google.spanner.v1.Spanner.ExecuteSql:input_type -> google.spanner.v1.ExecuteSqlRequest
- 13, // 60: google.spanner.v1.Spanner.ExecuteStreamingSql:input_type -> google.spanner.v1.ExecuteSqlRequest
- 14, // 61: google.spanner.v1.Spanner.ExecuteBatchDml:input_type -> google.spanner.v1.ExecuteBatchDmlRequest
- 21, // 62: google.spanner.v1.Spanner.Read:input_type -> google.spanner.v1.ReadRequest
- 21, // 63: google.spanner.v1.Spanner.StreamingRead:input_type -> google.spanner.v1.ReadRequest
- 22, // 64: google.spanner.v1.Spanner.BeginTransaction:input_type -> google.spanner.v1.BeginTransactionRequest
- 23, // 65: google.spanner.v1.Spanner.Commit:input_type -> google.spanner.v1.CommitRequest
- 24, // 66: google.spanner.v1.Spanner.Rollback:input_type -> google.spanner.v1.RollbackRequest
- 17, // 67: google.spanner.v1.Spanner.PartitionQuery:input_type -> google.spanner.v1.PartitionQueryRequest
- 18, // 68: google.spanner.v1.Spanner.PartitionRead:input_type -> google.spanner.v1.PartitionReadRequest
- 25, // 69: google.spanner.v1.Spanner.BatchWrite:input_type -> google.spanner.v1.BatchWriteRequest
- 6, // 70: google.spanner.v1.Spanner.CreateSession:output_type -> google.spanner.v1.Session
- 5, // 71: google.spanner.v1.Spanner.BatchCreateSessions:output_type -> google.spanner.v1.BatchCreateSessionsResponse
- 6, // 72: google.spanner.v1.Spanner.GetSession:output_type -> google.spanner.v1.Session
- 9, // 73: google.spanner.v1.Spanner.ListSessions:output_type -> google.spanner.v1.ListSessionsResponse
- 48, // 74: google.spanner.v1.Spanner.DeleteSession:output_type -> google.protobuf.Empty
- 40, // 75: google.spanner.v1.Spanner.ExecuteSql:output_type -> google.spanner.v1.ResultSet
- 49, // 76: google.spanner.v1.Spanner.ExecuteStreamingSql:output_type -> google.spanner.v1.PartialResultSet
- 15, // 77: google.spanner.v1.Spanner.ExecuteBatchDml:output_type -> google.spanner.v1.ExecuteBatchDmlResponse
- 40, // 78: google.spanner.v1.Spanner.Read:output_type -> google.spanner.v1.ResultSet
- 49, // 79: google.spanner.v1.Spanner.StreamingRead:output_type -> google.spanner.v1.PartialResultSet
- 43, // 80: google.spanner.v1.Spanner.BeginTransaction:output_type -> google.spanner.v1.Transaction
- 50, // 81: google.spanner.v1.Spanner.Commit:output_type -> google.spanner.v1.CommitResponse
- 48, // 82: google.spanner.v1.Spanner.Rollback:output_type -> google.protobuf.Empty
- 20, // 83: google.spanner.v1.Spanner.PartitionQuery:output_type -> google.spanner.v1.PartitionResponse
- 20, // 84: google.spanner.v1.Spanner.PartitionRead:output_type -> google.spanner.v1.PartitionResponse
- 26, // 85: google.spanner.v1.Spanner.BatchWrite:output_type -> google.spanner.v1.BatchWriteResponse
- 70, // [70:86] is the sub-list for method output_type
- 54, // [54:70] is the sub-list for method input_type
- 54, // [54:54] is the sub-list for extension type_name
- 54, // [54:54] is the sub-list for extension extendee
- 0, // [0:54] is the sub-list for field type_name
+ 33, // 14: google.spanner.v1.ExecuteSqlRequest.query_options:type_name -> google.spanner.v1.ExecuteSqlRequest.QueryOptions
+ 13, // 15: google.spanner.v1.ExecuteSqlRequest.request_options:type_name -> google.spanner.v1.RequestOptions
+ 14, // 16: google.spanner.v1.ExecuteSqlRequest.directed_read_options:type_name -> google.spanner.v1.DirectedReadOptions
+ 40, // 17: google.spanner.v1.ExecuteBatchDmlRequest.transaction:type_name -> google.spanner.v1.TransactionSelector
+ 35, // 18: google.spanner.v1.ExecuteBatchDmlRequest.statements:type_name -> google.spanner.v1.ExecuteBatchDmlRequest.Statement
+ 13, // 19: google.spanner.v1.ExecuteBatchDmlRequest.request_options:type_name -> google.spanner.v1.RequestOptions
+ 42, // 20: google.spanner.v1.ExecuteBatchDmlResponse.result_sets:type_name -> google.spanner.v1.ResultSet
+ 43, // 21: google.spanner.v1.ExecuteBatchDmlResponse.status:type_name -> google.rpc.Status
+ 40, // 22: google.spanner.v1.PartitionQueryRequest.transaction:type_name -> google.spanner.v1.TransactionSelector
+ 41, // 23: google.spanner.v1.PartitionQueryRequest.params:type_name -> google.protobuf.Struct
+ 37, // 24: google.spanner.v1.PartitionQueryRequest.param_types:type_name -> google.spanner.v1.PartitionQueryRequest.ParamTypesEntry
+ 18, // 25: google.spanner.v1.PartitionQueryRequest.partition_options:type_name -> google.spanner.v1.PartitionOptions
+ 40, // 26: google.spanner.v1.PartitionReadRequest.transaction:type_name -> google.spanner.v1.TransactionSelector
+ 44, // 27: google.spanner.v1.PartitionReadRequest.key_set:type_name -> google.spanner.v1.KeySet
+ 18, // 28: google.spanner.v1.PartitionReadRequest.partition_options:type_name -> google.spanner.v1.PartitionOptions
+ 21, // 29: google.spanner.v1.PartitionResponse.partitions:type_name -> google.spanner.v1.Partition
+ 45, // 30: google.spanner.v1.PartitionResponse.transaction:type_name -> google.spanner.v1.Transaction
+ 40, // 31: google.spanner.v1.ReadRequest.transaction:type_name -> google.spanner.v1.TransactionSelector
+ 44, // 32: google.spanner.v1.ReadRequest.key_set:type_name -> google.spanner.v1.KeySet
+ 13, // 33: google.spanner.v1.ReadRequest.request_options:type_name -> google.spanner.v1.RequestOptions
+ 14, // 34: google.spanner.v1.ReadRequest.directed_read_options:type_name -> google.spanner.v1.DirectedReadOptions
+ 3, // 35: google.spanner.v1.ReadRequest.order_by:type_name -> google.spanner.v1.ReadRequest.OrderBy
+ 4, // 36: google.spanner.v1.ReadRequest.lock_hint:type_name -> google.spanner.v1.ReadRequest.LockHint
+ 46, // 37: google.spanner.v1.BeginTransactionRequest.options:type_name -> google.spanner.v1.TransactionOptions
+ 13, // 38: google.spanner.v1.BeginTransactionRequest.request_options:type_name -> google.spanner.v1.RequestOptions
+ 46, // 39: google.spanner.v1.CommitRequest.single_use_transaction:type_name -> google.spanner.v1.TransactionOptions
+ 47, // 40: google.spanner.v1.CommitRequest.mutations:type_name -> google.spanner.v1.Mutation
+ 48, // 41: google.spanner.v1.CommitRequest.max_commit_delay:type_name -> google.protobuf.Duration
+ 13, // 42: google.spanner.v1.CommitRequest.request_options:type_name -> google.spanner.v1.RequestOptions
+ 13, // 43: google.spanner.v1.BatchWriteRequest.request_options:type_name -> google.spanner.v1.RequestOptions
+ 38, // 44: google.spanner.v1.BatchWriteRequest.mutation_groups:type_name -> google.spanner.v1.BatchWriteRequest.MutationGroup
+ 43, // 45: google.spanner.v1.BatchWriteResponse.status:type_name -> google.rpc.Status
+ 39, // 46: google.spanner.v1.BatchWriteResponse.commit_timestamp:type_name -> google.protobuf.Timestamp
+ 1, // 47: google.spanner.v1.DirectedReadOptions.ReplicaSelection.type:type_name -> google.spanner.v1.DirectedReadOptions.ReplicaSelection.Type
+ 30, // 48: google.spanner.v1.DirectedReadOptions.IncludeReplicas.replica_selections:type_name -> google.spanner.v1.DirectedReadOptions.ReplicaSelection
+ 30, // 49: google.spanner.v1.DirectedReadOptions.ExcludeReplicas.replica_selections:type_name -> google.spanner.v1.DirectedReadOptions.ReplicaSelection
+ 49, // 50: google.spanner.v1.ExecuteSqlRequest.ParamTypesEntry.value:type_name -> google.spanner.v1.Type
+ 41, // 51: google.spanner.v1.ExecuteBatchDmlRequest.Statement.params:type_name -> google.protobuf.Struct
+ 36, // 52: google.spanner.v1.ExecuteBatchDmlRequest.Statement.param_types:type_name -> google.spanner.v1.ExecuteBatchDmlRequest.Statement.ParamTypesEntry
+ 49, // 53: google.spanner.v1.ExecuteBatchDmlRequest.Statement.ParamTypesEntry.value:type_name -> google.spanner.v1.Type
+ 49, // 54: google.spanner.v1.PartitionQueryRequest.ParamTypesEntry.value:type_name -> google.spanner.v1.Type
+ 47, // 55: google.spanner.v1.BatchWriteRequest.MutationGroup.mutations:type_name -> google.spanner.v1.Mutation
+ 5, // 56: google.spanner.v1.Spanner.CreateSession:input_type -> google.spanner.v1.CreateSessionRequest
+ 6, // 57: google.spanner.v1.Spanner.BatchCreateSessions:input_type -> google.spanner.v1.BatchCreateSessionsRequest
+ 9, // 58: google.spanner.v1.Spanner.GetSession:input_type -> google.spanner.v1.GetSessionRequest
+ 10, // 59: google.spanner.v1.Spanner.ListSessions:input_type -> google.spanner.v1.ListSessionsRequest
+ 12, // 60: google.spanner.v1.Spanner.DeleteSession:input_type -> google.spanner.v1.DeleteSessionRequest
+ 15, // 61: google.spanner.v1.Spanner.ExecuteSql:input_type -> google.spanner.v1.ExecuteSqlRequest
+ 15, // 62: google.spanner.v1.Spanner.ExecuteStreamingSql:input_type -> google.spanner.v1.ExecuteSqlRequest
+ 16, // 63: google.spanner.v1.Spanner.ExecuteBatchDml:input_type -> google.spanner.v1.ExecuteBatchDmlRequest
+ 23, // 64: google.spanner.v1.Spanner.Read:input_type -> google.spanner.v1.ReadRequest
+ 23, // 65: google.spanner.v1.Spanner.StreamingRead:input_type -> google.spanner.v1.ReadRequest
+ 24, // 66: google.spanner.v1.Spanner.BeginTransaction:input_type -> google.spanner.v1.BeginTransactionRequest
+ 25, // 67: google.spanner.v1.Spanner.Commit:input_type -> google.spanner.v1.CommitRequest
+ 26, // 68: google.spanner.v1.Spanner.Rollback:input_type -> google.spanner.v1.RollbackRequest
+ 19, // 69: google.spanner.v1.Spanner.PartitionQuery:input_type -> google.spanner.v1.PartitionQueryRequest
+ 20, // 70: google.spanner.v1.Spanner.PartitionRead:input_type -> google.spanner.v1.PartitionReadRequest
+ 27, // 71: google.spanner.v1.Spanner.BatchWrite:input_type -> google.spanner.v1.BatchWriteRequest
+ 8, // 72: google.spanner.v1.Spanner.CreateSession:output_type -> google.spanner.v1.Session
+ 7, // 73: google.spanner.v1.Spanner.BatchCreateSessions:output_type -> google.spanner.v1.BatchCreateSessionsResponse
+ 8, // 74: google.spanner.v1.Spanner.GetSession:output_type -> google.spanner.v1.Session
+ 11, // 75: google.spanner.v1.Spanner.ListSessions:output_type -> google.spanner.v1.ListSessionsResponse
+ 50, // 76: google.spanner.v1.Spanner.DeleteSession:output_type -> google.protobuf.Empty
+ 42, // 77: google.spanner.v1.Spanner.ExecuteSql:output_type -> google.spanner.v1.ResultSet
+ 51, // 78: google.spanner.v1.Spanner.ExecuteStreamingSql:output_type -> google.spanner.v1.PartialResultSet
+ 17, // 79: google.spanner.v1.Spanner.ExecuteBatchDml:output_type -> google.spanner.v1.ExecuteBatchDmlResponse
+ 42, // 80: google.spanner.v1.Spanner.Read:output_type -> google.spanner.v1.ResultSet
+ 51, // 81: google.spanner.v1.Spanner.StreamingRead:output_type -> google.spanner.v1.PartialResultSet
+ 45, // 82: google.spanner.v1.Spanner.BeginTransaction:output_type -> google.spanner.v1.Transaction
+ 52, // 83: google.spanner.v1.Spanner.Commit:output_type -> google.spanner.v1.CommitResponse
+ 50, // 84: google.spanner.v1.Spanner.Rollback:output_type -> google.protobuf.Empty
+ 22, // 85: google.spanner.v1.Spanner.PartitionQuery:output_type -> google.spanner.v1.PartitionResponse
+ 22, // 86: google.spanner.v1.Spanner.PartitionRead:output_type -> google.spanner.v1.PartitionResponse
+ 28, // 87: google.spanner.v1.Spanner.BatchWrite:output_type -> google.spanner.v1.BatchWriteResponse
+ 72, // [72:88] is the sub-list for method output_type
+ 56, // [56:72] is the sub-list for method input_type
+ 56, // [56:56] is the sub-list for extension type_name
+ 56, // [56:56] is the sub-list for extension extendee
+ 0, // [0:56] is the sub-list for field type_name
}
func init() { file_google_spanner_v1_spanner_proto_init() }
@@ -3718,7 +3914,7 @@ func file_google_spanner_v1_spanner_proto_init() {
file_google_spanner_v1_transaction_proto_init()
file_google_spanner_v1_type_proto_init()
if !protoimpl.UnsafeEnabled {
- file_google_spanner_v1_spanner_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*CreateSessionRequest); i {
case 0:
return &v.state
@@ -3730,7 +3926,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*BatchCreateSessionsRequest); i {
case 0:
return &v.state
@@ -3742,7 +3938,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[2].Exporter = func(v any, i int) any {
switch v := v.(*BatchCreateSessionsResponse); i {
case 0:
return &v.state
@@ -3754,7 +3950,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[3].Exporter = func(v any, i int) any {
switch v := v.(*Session); i {
case 0:
return &v.state
@@ -3766,7 +3962,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[4].Exporter = func(v any, i int) any {
switch v := v.(*GetSessionRequest); i {
case 0:
return &v.state
@@ -3778,7 +3974,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[5].Exporter = func(v any, i int) any {
switch v := v.(*ListSessionsRequest); i {
case 0:
return &v.state
@@ -3790,7 +3986,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[6].Exporter = func(v any, i int) any {
switch v := v.(*ListSessionsResponse); i {
case 0:
return &v.state
@@ -3802,7 +3998,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[7].Exporter = func(v any, i int) any {
switch v := v.(*DeleteSessionRequest); i {
case 0:
return &v.state
@@ -3814,7 +4010,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[8].Exporter = func(v any, i int) any {
switch v := v.(*RequestOptions); i {
case 0:
return &v.state
@@ -3826,7 +4022,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[9].Exporter = func(v any, i int) any {
switch v := v.(*DirectedReadOptions); i {
case 0:
return &v.state
@@ -3838,7 +4034,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[10].Exporter = func(v any, i int) any {
switch v := v.(*ExecuteSqlRequest); i {
case 0:
return &v.state
@@ -3850,7 +4046,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[11].Exporter = func(v any, i int) any {
switch v := v.(*ExecuteBatchDmlRequest); i {
case 0:
return &v.state
@@ -3862,7 +4058,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[12].Exporter = func(v any, i int) any {
switch v := v.(*ExecuteBatchDmlResponse); i {
case 0:
return &v.state
@@ -3874,7 +4070,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[13].Exporter = func(v any, i int) any {
switch v := v.(*PartitionOptions); i {
case 0:
return &v.state
@@ -3886,7 +4082,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[14].Exporter = func(v any, i int) any {
switch v := v.(*PartitionQueryRequest); i {
case 0:
return &v.state
@@ -3898,7 +4094,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[15].Exporter = func(v any, i int) any {
switch v := v.(*PartitionReadRequest); i {
case 0:
return &v.state
@@ -3910,7 +4106,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[16].Exporter = func(v any, i int) any {
switch v := v.(*Partition); i {
case 0:
return &v.state
@@ -3922,7 +4118,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[17].Exporter = func(v any, i int) any {
switch v := v.(*PartitionResponse); i {
case 0:
return &v.state
@@ -3934,7 +4130,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[18].Exporter = func(v any, i int) any {
switch v := v.(*ReadRequest); i {
case 0:
return &v.state
@@ -3946,7 +4142,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[19].Exporter = func(v any, i int) any {
switch v := v.(*BeginTransactionRequest); i {
case 0:
return &v.state
@@ -3958,7 +4154,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[20].Exporter = func(v any, i int) any {
switch v := v.(*CommitRequest); i {
case 0:
return &v.state
@@ -3970,7 +4166,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[21].Exporter = func(v any, i int) any {
switch v := v.(*RollbackRequest); i {
case 0:
return &v.state
@@ -3982,7 +4178,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[22].Exporter = func(v any, i int) any {
switch v := v.(*BatchWriteRequest); i {
case 0:
return &v.state
@@ -3994,7 +4190,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[23].Exporter = func(v any, i int) any {
switch v := v.(*BatchWriteResponse); i {
case 0:
return &v.state
@@ -4006,7 +4202,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[25].Exporter = func(v any, i int) any {
switch v := v.(*DirectedReadOptions_ReplicaSelection); i {
case 0:
return &v.state
@@ -4018,7 +4214,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[26].Exporter = func(v any, i int) any {
switch v := v.(*DirectedReadOptions_IncludeReplicas); i {
case 0:
return &v.state
@@ -4030,7 +4226,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[27].Exporter = func(v any, i int) any {
switch v := v.(*DirectedReadOptions_ExcludeReplicas); i {
case 0:
return &v.state
@@ -4042,7 +4238,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[28].Exporter = func(v any, i int) any {
switch v := v.(*ExecuteSqlRequest_QueryOptions); i {
case 0:
return &v.state
@@ -4054,7 +4250,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[30].Exporter = func(v any, i int) any {
switch v := v.(*ExecuteBatchDmlRequest_Statement); i {
case 0:
return &v.state
@@ -4066,7 +4262,7 @@ func file_google_spanner_v1_spanner_proto_init() {
return nil
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_spanner_proto_msgTypes[33].Exporter = func(v any, i int) any {
switch v := v.(*BatchWriteRequest_MutationGroup); i {
case 0:
return &v.state
@@ -4079,11 +4275,11 @@ func file_google_spanner_v1_spanner_proto_init() {
}
}
}
- file_google_spanner_v1_spanner_proto_msgTypes[9].OneofWrappers = []interface{}{
+ file_google_spanner_v1_spanner_proto_msgTypes[9].OneofWrappers = []any{
(*DirectedReadOptions_IncludeReplicas_)(nil),
(*DirectedReadOptions_ExcludeReplicas_)(nil),
}
- file_google_spanner_v1_spanner_proto_msgTypes[20].OneofWrappers = []interface{}{
+ file_google_spanner_v1_spanner_proto_msgTypes[20].OneofWrappers = []any{
(*CommitRequest_TransactionId)(nil),
(*CommitRequest_SingleUseTransaction)(nil),
}
@@ -4092,7 +4288,7 @@ func file_google_spanner_v1_spanner_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_google_spanner_v1_spanner_proto_rawDesc,
- NumEnums: 3,
+ NumEnums: 5,
NumMessages: 34,
NumExtensions: 0,
NumServices: 1,
diff --git a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/transaction.pb.go b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/transaction.pb.go
index 507bb4214..829120c1c 100644
--- a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/transaction.pb.go
+++ b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/transaction.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2023 Google LLC
+// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.32.0
-// protoc v4.25.2
+// protoc-gen-go v1.34.2
+// protoc v4.25.3
// source: google/spanner/v1/transaction.proto
package spannerpb
@@ -1130,7 +1130,7 @@ func file_google_spanner_v1_transaction_proto_rawDescGZIP() []byte {
var file_google_spanner_v1_transaction_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_google_spanner_v1_transaction_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
-var file_google_spanner_v1_transaction_proto_goTypes = []interface{}{
+var file_google_spanner_v1_transaction_proto_goTypes = []any{
(TransactionOptions_ReadWrite_ReadLockMode)(0), // 0: google.spanner.v1.TransactionOptions.ReadWrite.ReadLockMode
(*TransactionOptions)(nil), // 1: google.spanner.v1.TransactionOptions
(*Transaction)(nil), // 2: google.spanner.v1.Transaction
@@ -1166,7 +1166,7 @@ func file_google_spanner_v1_transaction_proto_init() {
return
}
if !protoimpl.UnsafeEnabled {
- file_google_spanner_v1_transaction_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_transaction_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*TransactionOptions); i {
case 0:
return &v.state
@@ -1178,7 +1178,7 @@ func file_google_spanner_v1_transaction_proto_init() {
return nil
}
}
- file_google_spanner_v1_transaction_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_transaction_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*Transaction); i {
case 0:
return &v.state
@@ -1190,7 +1190,7 @@ func file_google_spanner_v1_transaction_proto_init() {
return nil
}
}
- file_google_spanner_v1_transaction_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_transaction_proto_msgTypes[2].Exporter = func(v any, i int) any {
switch v := v.(*TransactionSelector); i {
case 0:
return &v.state
@@ -1202,7 +1202,7 @@ func file_google_spanner_v1_transaction_proto_init() {
return nil
}
}
- file_google_spanner_v1_transaction_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_transaction_proto_msgTypes[3].Exporter = func(v any, i int) any {
switch v := v.(*TransactionOptions_ReadWrite); i {
case 0:
return &v.state
@@ -1214,7 +1214,7 @@ func file_google_spanner_v1_transaction_proto_init() {
return nil
}
}
- file_google_spanner_v1_transaction_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_transaction_proto_msgTypes[4].Exporter = func(v any, i int) any {
switch v := v.(*TransactionOptions_PartitionedDml); i {
case 0:
return &v.state
@@ -1226,7 +1226,7 @@ func file_google_spanner_v1_transaction_proto_init() {
return nil
}
}
- file_google_spanner_v1_transaction_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_transaction_proto_msgTypes[5].Exporter = func(v any, i int) any {
switch v := v.(*TransactionOptions_ReadOnly); i {
case 0:
return &v.state
@@ -1239,17 +1239,17 @@ func file_google_spanner_v1_transaction_proto_init() {
}
}
}
- file_google_spanner_v1_transaction_proto_msgTypes[0].OneofWrappers = []interface{}{
+ file_google_spanner_v1_transaction_proto_msgTypes[0].OneofWrappers = []any{
(*TransactionOptions_ReadWrite_)(nil),
(*TransactionOptions_PartitionedDml_)(nil),
(*TransactionOptions_ReadOnly_)(nil),
}
- file_google_spanner_v1_transaction_proto_msgTypes[2].OneofWrappers = []interface{}{
+ file_google_spanner_v1_transaction_proto_msgTypes[2].OneofWrappers = []any{
(*TransactionSelector_SingleUse)(nil),
(*TransactionSelector_Id)(nil),
(*TransactionSelector_Begin)(nil),
}
- file_google_spanner_v1_transaction_proto_msgTypes[5].OneofWrappers = []interface{}{
+ file_google_spanner_v1_transaction_proto_msgTypes[5].OneofWrappers = []any{
(*TransactionOptions_ReadOnly_Strong)(nil),
(*TransactionOptions_ReadOnly_MinReadTimestamp)(nil),
(*TransactionOptions_ReadOnly_MaxStaleness)(nil),
diff --git a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/type.pb.go b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/type.pb.go
index a3780def8..0c30a4f54 100644
--- a/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/type.pb.go
+++ b/vendor/cloud.google.com/go/spanner/apiv1/spannerpb/type.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2023 Google LLC
+// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.32.0
-// protoc v4.25.2
+// protoc-gen-go v1.34.2
+// protoc v4.25.3
// source: google/spanner/v1/type.proto
package spannerpb
@@ -544,7 +544,7 @@ func file_google_spanner_v1_type_proto_rawDescGZIP() []byte {
var file_google_spanner_v1_type_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_google_spanner_v1_type_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_google_spanner_v1_type_proto_goTypes = []interface{}{
+var file_google_spanner_v1_type_proto_goTypes = []any{
(TypeCode)(0), // 0: google.spanner.v1.TypeCode
(TypeAnnotationCode)(0), // 1: google.spanner.v1.TypeAnnotationCode
(*Type)(nil), // 2: google.spanner.v1.Type
@@ -571,7 +571,7 @@ func file_google_spanner_v1_type_proto_init() {
return
}
if !protoimpl.UnsafeEnabled {
- file_google_spanner_v1_type_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_type_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*Type); i {
case 0:
return &v.state
@@ -583,7 +583,7 @@ func file_google_spanner_v1_type_proto_init() {
return nil
}
}
- file_google_spanner_v1_type_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_type_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*StructType); i {
case 0:
return &v.state
@@ -595,7 +595,7 @@ func file_google_spanner_v1_type_proto_init() {
return nil
}
}
- file_google_spanner_v1_type_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ file_google_spanner_v1_type_proto_msgTypes[2].Exporter = func(v any, i int) any {
switch v := v.(*StructType_Field); i {
case 0:
return &v.state
diff --git a/vendor/cloud.google.com/go/spanner/batch.go b/vendor/cloud.google.com/go/spanner/batch.go
index 2046ba1ba..5c20f66fb 100644
--- a/vendor/cloud.google.com/go/spanner/batch.go
+++ b/vendor/cloud.google.com/go/spanner/batch.go
@@ -25,10 +25,10 @@ import (
"cloud.google.com/go/internal/trace"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
- "github.com/golang/protobuf/proto"
"github.com/googleapis/gax-go/v2"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
+ "google.golang.org/protobuf/proto"
)
// BatchReadOnlyTransaction is a ReadOnlyTransaction that allows for exporting
diff --git a/vendor/cloud.google.com/go/spanner/client.go b/vendor/cloud.google.com/go/spanner/client.go
index fe87fafb1..5d3d078a5 100644
--- a/vendor/cloud.google.com/go/spanner/client.go
+++ b/vendor/cloud.google.com/go/spanner/client.go
@@ -28,6 +28,8 @@ import (
"cloud.google.com/go/internal/trace"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
+ "github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp"
+ grpcgcppb "github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp/grpc_gcp"
"github.com/googleapis/gax-go/v2"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
@@ -37,6 +39,7 @@ import (
gtransport "google.golang.org/api/transport/grpc"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
+ "google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/encoding/gzip"
"google.golang.org/grpc/metadata"
@@ -121,6 +124,131 @@ func (c *Client) ClientID() string {
return c.sc.id
}
+func createGCPMultiEndpoint(cfg *grpcgcp.GCPMultiEndpointOptions, config ClientConfig, opts ...option.ClientOption) (*grpcgcp.GCPMultiEndpoint, error) {
+ if cfg.GRPCgcpConfig == nil {
+ cfg.GRPCgcpConfig = &grpcgcppb.ApiConfig{}
+ }
+ if cfg.GRPCgcpConfig.Method == nil || len(cfg.GRPCgcpConfig.Method) == 0 {
+ cfg.GRPCgcpConfig.Method = []*grpcgcppb.MethodConfig{
+ {
+ Name: []string{"/google.spanner.v1.Spanner/CreateSession"},
+ Affinity: &grpcgcppb.AffinityConfig{
+ Command: grpcgcppb.AffinityConfig_BIND,
+ AffinityKey: "name",
+ },
+ },
+ {
+ Name: []string{"/google.spanner.v1.Spanner/BatchCreateSessions"},
+ Affinity: &grpcgcppb.AffinityConfig{
+ Command: grpcgcppb.AffinityConfig_BIND,
+ AffinityKey: "session.name",
+ },
+ },
+ {
+ Name: []string{"/google.spanner.v1.Spanner/DeleteSession"},
+ Affinity: &grpcgcppb.AffinityConfig{
+ Command: grpcgcppb.AffinityConfig_UNBIND,
+ AffinityKey: "name",
+ },
+ },
+ {
+ Name: []string{"/google.spanner.v1.Spanner/GetSession"},
+ Affinity: &grpcgcppb.AffinityConfig{
+ Command: grpcgcppb.AffinityConfig_BOUND,
+ AffinityKey: "name",
+ },
+ },
+ {
+ Name: []string{
+ "/google.spanner.v1.Spanner/BeginTransaction",
+ "/google.spanner.v1.Spanner/Commit",
+ "/google.spanner.v1.Spanner/ExecuteBatchDml",
+ "/google.spanner.v1.Spanner/ExecuteSql",
+ "/google.spanner.v1.Spanner/ExecuteStreamingSql",
+ "/google.spanner.v1.Spanner/PartitionQuery",
+ "/google.spanner.v1.Spanner/PartitionRead",
+ "/google.spanner.v1.Spanner/Read",
+ "/google.spanner.v1.Spanner/Rollback",
+ "/google.spanner.v1.Spanner/StreamingRead",
+ },
+ Affinity: &grpcgcppb.AffinityConfig{
+ Command: grpcgcppb.AffinityConfig_BOUND,
+ AffinityKey: "session",
+ },
+ },
+ }
+ }
+ // Append emulator options if SPANNER_EMULATOR_HOST has been set.
+ if emulatorAddr := os.Getenv("SPANNER_EMULATOR_HOST"); emulatorAddr != "" {
+ emulatorOpts := []option.ClientOption{
+ option.WithEndpoint(emulatorAddr),
+ option.WithGRPCDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())),
+ option.WithoutAuthentication(),
+ internaloption.SkipDialSettingsValidation(),
+ }
+ opts = append(opts, emulatorOpts...)
+ // Replace all endpoints with emulator target.
+ for _, meo := range cfg.MultiEndpoints {
+ meo.Endpoints = []string{emulatorAddr}
+ }
+ }
+
+ // Set the number of channels to the default value if not specified.
+ if cfg.GRPCgcpConfig.GetChannelPool() == nil || cfg.GRPCgcpConfig.GetChannelPool().GetMaxSize() == 0 {
+ cfg.GRPCgcpConfig.ChannelPool = &grpcgcppb.ChannelPoolConfig{
+ MinSize: numChannels,
+ MaxSize: numChannels,
+ }
+ }
+ // Set MinSize equal to MaxSize to create all the channels beforehand.
+ cfg.GRPCgcpConfig.ChannelPool.MinSize = cfg.GRPCgcpConfig.ChannelPool.GetMaxSize()
+
+ cfg.GRPCgcpConfig.ChannelPool.BindPickStrategy = grpcgcppb.ChannelPoolConfig_ROUND_ROBIN
+
+ cfg.DialFunc = func(ctx context.Context, target string, dopts ...grpc.DialOption) (*grpc.ClientConn, error) {
+ copts := opts
+
+ for _, do := range dopts {
+ copts = append(copts, option.WithGRPCDialOption(do))
+ }
+
+ allOpts := allClientOpts(1, config.Compression, copts...)
+
+ // Overwrite endpoint and pool config.
+ allOpts = append(allOpts,
+ option.WithEndpoint(target),
+ option.WithGRPCConnectionPool(1),
+ option.WithGRPCConn(nil),
+ )
+
+ return gtransport.Dial(ctx, allOpts...)
+ }
+
+ gme, err := grpcgcp.NewGCPMultiEndpoint(cfg)
+ return gme, err
+}
+
+// To use GCPMultiEndpoint in gtransport.Dial (via gtransport.WithConnPool option)
+// we implement gtransport.ConnPool interface using this wrapper.
+type gmeWrapper struct {
+ *grpcgcp.GCPMultiEndpoint
+}
+
+// Make sure gmeWrapper implements ConnPool interface.
+var _ gtransport.ConnPool = (*gmeWrapper)(nil)
+
+func (gw *gmeWrapper) Conn() *grpc.ClientConn {
+ // GCPMultiEndpoint does not expose any ClientConn.
+ // This is safe because Cloud Spanner client doesn't use this function and instead
+ // makes calls directly using Invoke and NewStream from the grpc.ClientConnInterface
+ // which GCPMultiEndpoint implements.
+ return nil
+}
+
+func (gw *gmeWrapper) Num() int {
+ return int(gw.GCPMultiEndpoint.GCPConfig().GetChannelPool().GetMaxSize())
+}
+
// ClientConfig has configurations for the client.
type ClientConfig struct {
// NumChannels is the number of gRPC channels.
@@ -206,18 +334,20 @@ type ClientConfig struct {
}
type openTelemetryConfig struct {
- meterProvider metric.MeterProvider
- attributeMap []attribute.KeyValue
- otMetricRegistration metric.Registration
- openSessionCount metric.Int64ObservableGauge
- maxAllowedSessionsCount metric.Int64ObservableGauge
- sessionsCount metric.Int64ObservableGauge
- maxInUseSessionsCount metric.Int64ObservableGauge
- getSessionTimeoutsCount metric.Int64Counter
- acquiredSessionsCount metric.Int64Counter
- releasedSessionsCount metric.Int64Counter
- gfeLatency metric.Int64Histogram
- gfeHeaderMissingCount metric.Int64Counter
+ meterProvider metric.MeterProvider
+ attributeMap []attribute.KeyValue
+ attributeMapWithMultiplexed []attribute.KeyValue
+ attributeMapWithoutMultiplexed []attribute.KeyValue
+ otMetricRegistration metric.Registration
+ openSessionCount metric.Int64ObservableGauge
+ maxAllowedSessionsCount metric.Int64ObservableGauge
+ sessionsCount metric.Int64ObservableGauge
+ maxInUseSessionsCount metric.Int64ObservableGauge
+ getSessionTimeoutsCount metric.Int64Counter
+ acquiredSessionsCount metric.Int64Counter
+ releasedSessionsCount metric.Int64Counter
+ gfeLatency metric.Int64Histogram
+ gfeHeaderMissingCount metric.Int64Counter
}
func contextWithOutgoingMetadata(ctx context.Context, md metadata.MD, disableRouteToLeader bool) context.Context {
@@ -241,6 +371,10 @@ func NewClient(ctx context.Context, database string, opts ...option.ClientOption
// NewClientWithConfig creates a client to a database. A valid database name has
// the form projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID.
func NewClientWithConfig(ctx context.Context, database string, config ClientConfig, opts ...option.ClientOption) (c *Client, err error) {
+ return newClientWithConfig(ctx, database, config, nil, opts...)
+}
+
+func newClientWithConfig(ctx context.Context, database string, config ClientConfig, gme *grpcgcp.GCPMultiEndpoint, opts ...option.ClientOption) (c *Client, err error) {
// Validate database path.
if err := validDatabaseName(database); err != nil {
return nil, err
@@ -253,7 +387,7 @@ func NewClientWithConfig(ctx context.Context, database string, config ClientConf
if emulatorAddr := os.Getenv("SPANNER_EMULATOR_HOST"); emulatorAddr != "" {
emulatorOpts := []option.ClientOption{
option.WithEndpoint(emulatorAddr),
- option.WithGRPCDialOption(grpc.WithInsecure()),
+ option.WithGRPCDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())),
option.WithoutAuthentication(),
internaloption.SkipDialSettingsValidation(),
}
@@ -265,16 +399,25 @@ func NewClientWithConfig(ctx context.Context, database string, config ClientConf
if config.NumChannels == 0 {
config.NumChannels = numChannels
}
- // gRPC options.
- allOpts := allClientOpts(config.NumChannels, config.Compression, opts...)
- pool, err := gtransport.DialPool(ctx, allOpts...)
- if err != nil {
- return nil, err
- }
- if hasNumChannelsConfig && pool.Num() != config.NumChannels {
- pool.Close()
- return nil, spannerErrorf(codes.InvalidArgument, "Connection pool mismatch: NumChannels=%v, WithGRPCConnectionPool=%v. Only set one of these options, or set both to the same value.", config.NumChannels, pool.Num())
+ var pool gtransport.ConnPool
+
+ if gme != nil {
+ // Use GCPMultiEndpoint if provided.
+ pool = &gmeWrapper{gme}
+ } else {
+ // Create gtransport ConnPool as usual if MultiEndpoint is not used.
+ // gRPC options.
+ allOpts := allClientOpts(config.NumChannels, config.Compression, opts...)
+ pool, err = gtransport.DialPool(ctx, allOpts...)
+ if err != nil {
+ return nil, err
+ }
+
+ if hasNumChannelsConfig && pool.Num() != config.NumChannels {
+ pool.Close()
+ return nil, spannerErrorf(codes.InvalidArgument, "Connection pool mismatch: NumChannels=%v, WithGRPCConnectionPool=%v. Only set one of these options, or set both to the same value.", config.NumChannels, pool.Num())
+ }
}
// TODO(loite): Remove as the original map cannot be changed by the user
@@ -343,6 +486,48 @@ func NewClientWithConfig(ctx context.Context, database string, config ClientConf
return c, nil
}
+// NewMultiEndpointClient is the same as NewMultiEndpointClientWithConfig with
+// the default client configuration.
+//
+// A valid database name has the
+// form projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID.
+func NewMultiEndpointClient(ctx context.Context, database string, gmeCfg *grpcgcp.GCPMultiEndpointOptions, opts ...option.ClientOption) (*Client, *grpcgcp.GCPMultiEndpoint, error) {
+ return NewMultiEndpointClientWithConfig(ctx, database, ClientConfig{SessionPoolConfig: DefaultSessionPoolConfig, DisableRouteToLeader: false}, gmeCfg, opts...)
+}
+
+// NewMultiEndpointClientWithConfig creates a client to a database using GCPMultiEndpoint.
+//
+// The purposes of GCPMultiEndpoint are:
+//
+// - Fallback to an alternative endpoint (host:port) when the original
+// endpoint is completely unavailable.
+// - Be able to route a Cloud Spanner call to a specific group of endpoints.
+// - Be able to reconfigure endpoints in runtime.
+//
+// The GRPCgcpConfig and DialFunc in the GCPMultiEndpointOptions are optional
+// and will be configured automatically.
+//
+// For GCPMultiEndpoint the number of channels is configured via MaxSize of the
+// ChannelPool config in the GRPCgcpConfig.
+//
+// The GCPMultiEndpoint returned can be used to update the endpoints in runtime.
+//
+// A valid database name has the
+// form projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID.
+func NewMultiEndpointClientWithConfig(ctx context.Context, database string, config ClientConfig, gmeCfg *grpcgcp.GCPMultiEndpointOptions, opts ...option.ClientOption) (c *Client, gme *grpcgcp.GCPMultiEndpoint, err error) {
+ gme, err = createGCPMultiEndpoint(gmeCfg, config, opts...)
+ if err != nil {
+ return nil, nil, err
+ }
+ // Align number of channels.
+ config.NumChannels = int(gme.GCPConfig().GetChannelPool().GetMaxSize())
+ c, err = newClientWithConfig(ctx, database, config, gme, opts...)
+ if err != nil {
+ return nil, nil, err
+ }
+ return
+}
+
// Combines the default options from the generated client, the default options
// of the hand-written client and the user options to one list of options.
// Precedence: userOpts > clientDefaultOpts > generatedDefaultOpts
@@ -351,11 +536,10 @@ func allClientOpts(numChannels int, compression string, userOpts ...option.Clien
clientDefaultOpts := []option.ClientOption{
option.WithGRPCConnectionPool(numChannels),
option.WithUserAgent(fmt.Sprintf("spanner-go/v%s", internal.Version)),
- internaloption.EnableDirectPath(true),
internaloption.AllowNonDefaultServiceAccount(true),
}
if enableDirectPathXds, _ := strconv.ParseBool(os.Getenv("GOOGLE_SPANNER_ENABLE_DIRECT_ACCESS")); enableDirectPathXds {
- clientDefaultOpts = append(clientDefaultOpts, internaloption.EnableDirectPathXds())
+ clientDefaultOpts = append(clientDefaultOpts, internaloption.EnableDirectPath(true), internaloption.EnableDirectPathXds())
}
if compression == "gzip" {
userOpts = append(userOpts, option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
@@ -427,6 +611,7 @@ func (c *Client) Single() *ReadOnlyTransaction {
}
t.txReadOnly.qo.DirectedReadOptions = c.dro
t.txReadOnly.ro.DirectedReadOptions = c.dro
+ t.txReadOnly.ro.LockHint = sppb.ReadRequest_LOCK_HINT_UNSPECIFIED
t.ct = c.ct
t.otConfig = c.otConfig
return t
@@ -453,6 +638,7 @@ func (c *Client) ReadOnlyTransaction() *ReadOnlyTransaction {
t.txReadOnly.disableRouteToLeader = true
t.txReadOnly.qo.DirectedReadOptions = c.dro
t.txReadOnly.ro.DirectedReadOptions = c.dro
+ t.txReadOnly.ro.LockHint = sppb.ReadRequest_LOCK_HINT_UNSPECIFIED
t.ct = c.ct
t.otConfig = c.otConfig
return t
@@ -524,6 +710,7 @@ func (c *Client) BatchReadOnlyTransaction(ctx context.Context, tb TimestampBound
t.txReadOnly.disableRouteToLeader = true
t.txReadOnly.qo.DirectedReadOptions = c.dro
t.txReadOnly.ro.DirectedReadOptions = c.dro
+ t.txReadOnly.ro.LockHint = sppb.ReadRequest_LOCK_HINT_UNSPECIFIED
t.ct = c.ct
t.otConfig = c.otConfig
return t, nil
@@ -558,6 +745,7 @@ func (c *Client) BatchReadOnlyTransactionFromID(tid BatchReadOnlyTransactionID)
t.txReadOnly.disableRouteToLeader = true
t.txReadOnly.qo.DirectedReadOptions = c.dro
t.txReadOnly.ro.DirectedReadOptions = c.dro
+ t.txReadOnly.ro.LockHint = sppb.ReadRequest_LOCK_HINT_UNSPECIFIED
t.ct = c.ct
t.otConfig = c.otConfig
return t
@@ -684,6 +872,12 @@ type applyOption struct {
transactionTag string
// priority is the RPC priority that is used for the commit operation.
priority sppb.RequestOptions_Priority
+ // If excludeTxnFromChangeStreams == true, mutations from this Client.Apply
+ // will not be recorded in allowed tracking change streams with DDL option
+ // allow_txn_exclusion=true.
+ excludeTxnFromChangeStreams bool
+ // commitOptions is the commit options to use for the commit operation.
+ commitOptions CommitOptions
}
// An ApplyOption is an optional argument to Apply.
@@ -722,6 +916,20 @@ func Priority(priority sppb.RequestOptions_Priority) ApplyOption {
}
}
+// ExcludeTxnFromChangeStreams returns an ApplyOptions that sets whether to exclude recording this commit operation from allowed tracking change streams.
+func ExcludeTxnFromChangeStreams() ApplyOption {
+ return func(ao *applyOption) {
+ ao.excludeTxnFromChangeStreams = true
+ }
+}
+
+// ApplyCommitOptions returns an ApplyOption that sets the commit options to use for the commit operation.
+func ApplyCommitOptions(co CommitOptions) ApplyOption {
+ return func(ao *applyOption) {
+ ao.commitOptions = co
+ }
+}
+
// Apply applies a list of mutations atomically to the database.
func (c *Client) Apply(ctx context.Context, ms []*Mutation, opts ...ApplyOption) (commitTimestamp time.Time, err error) {
ao := &applyOption{}
@@ -740,10 +948,10 @@ func (c *Client) Apply(ctx context.Context, ms []*Mutation, opts ...ApplyOption)
if !ao.atLeastOnce {
resp, err := c.ReadWriteTransactionWithOptions(ctx, func(ctx context.Context, t *ReadWriteTransaction) error {
return t.BufferWrite(ms)
- }, TransactionOptions{CommitPriority: ao.priority, TransactionTag: ao.transactionTag})
+ }, TransactionOptions{CommitPriority: ao.priority, TransactionTag: ao.transactionTag, ExcludeTxnFromChangeStreams: ao.excludeTxnFromChangeStreams, CommitOptions: ao.commitOptions})
return resp.CommitTs, err
}
- t := &writeOnlyTransaction{sp: c.idleSessions, commitPriority: ao.priority, transactionTag: ao.transactionTag, disableRouteToLeader: c.disableRouteToLeader}
+ t := &writeOnlyTransaction{sp: c.idleSessions, commitPriority: ao.priority, transactionTag: ao.transactionTag, disableRouteToLeader: c.disableRouteToLeader, excludeTxnFromChangeStreams: ao.excludeTxnFromChangeStreams, commitOptions: ao.commitOptions}
return t.applyAtLeastOnce(ctx, ms...)
}
@@ -754,14 +962,20 @@ type BatchWriteOptions struct {
// The transaction tag to use for this request.
TransactionTag string
+
+ // If excludeTxnFromChangeStreams == true, modifications from all transactions
+ // in this batch write request will not be recorded in allowed tracking
+ // change treams with DDL option allow_txn_exclusion=true.
+ ExcludeTxnFromChangeStreams bool
}
// merge combines two BatchWriteOptions such that the input parameter will have higher
// order of precedence.
func (bwo BatchWriteOptions) merge(opts BatchWriteOptions) BatchWriteOptions {
merged := BatchWriteOptions{
- TransactionTag: bwo.TransactionTag,
- Priority: bwo.Priority,
+ TransactionTag: bwo.TransactionTag,
+ Priority: bwo.Priority,
+ ExcludeTxnFromChangeStreams: bwo.ExcludeTxnFromChangeStreams || opts.ExcludeTxnFromChangeStreams,
}
if opts.TransactionTag != "" {
merged.TransactionTag = opts.TransactionTag
@@ -916,9 +1130,10 @@ func (c *Client) BatchWriteWithOptions(ctx context.Context, mgs []*MutationGroup
var md metadata.MD
sh.updateLastUseTime()
stream, rpcErr := sh.getClient().BatchWrite(contextWithOutgoingMetadata(ct, sh.getMetadata(), c.disableRouteToLeader), &sppb.BatchWriteRequest{
- Session: sh.getID(),
- MutationGroups: mgsPb,
- RequestOptions: createRequestOptions(opts.Priority, "", opts.TransactionTag),
+ Session: sh.getID(),
+ MutationGroups: mgsPb,
+ RequestOptions: createRequestOptions(opts.Priority, "", opts.TransactionTag),
+ ExcludeTxnFromChangeStreams: opts.ExcludeTxnFromChangeStreams,
}, gax.WithGRPCOptions(grpc.Header(&md)))
if getGFELatencyMetricsFlag() && md != nil && c.ct != nil {
diff --git a/vendor/cloud.google.com/go/spanner/emulator_test.sh b/vendor/cloud.google.com/go/spanner/emulator_test.sh
index fc326d83f..8fe69dba7 100644
--- a/vendor/cloud.google.com/go/spanner/emulator_test.sh
+++ b/vendor/cloud.google.com/go/spanner/emulator_test.sh
@@ -44,4 +44,8 @@ function cleanup() {
}
trap cleanup EXIT
-go test -v -timeout 10m ./... -run '^TestIntegration_' 2>&1 | tee -a sponge_log.log
+echo "Testing without GCPMultiEnpoint..." | tee -a sponge_log.log
+go test -count=1 -v -timeout 10m ./... -run '^TestIntegration_' 2>&1 | tee -a sponge_log.log
+
+echo "Testing with GCPMultiEnpoint..." | tee -a sponge_log.log
+GCLOUD_TESTS_GOLANG_USE_GRPC_GCP=true go test -count=1 -v -timeout 10m ./... -run '^TestIntegration_' 2>&1 | tee -a sponge_log.log
diff --git a/vendor/cloud.google.com/go/spanner/errors.go b/vendor/cloud.google.com/go/spanner/errors.go
index f44518127..ddf506bd5 100644
--- a/vendor/cloud.google.com/go/spanner/errors.go
+++ b/vendor/cloud.google.com/go/spanner/errors.go
@@ -18,6 +18,7 @@ package spanner
import (
"context"
+ "errors"
"fmt"
"github.com/googleapis/gax-go/v2/apierror"
@@ -26,6 +27,11 @@ import (
"google.golang.org/grpc/status"
)
+var (
+ // ErrRowNotFound row not found error
+ ErrRowNotFound = errors.New("row not found")
+)
+
// Error is the structured error returned by Cloud Spanner client.
//
// Deprecated: Unwrap any error that is returned by the Spanner client as an APIError
diff --git a/vendor/cloud.google.com/go/spanner/internal/version.go b/vendor/cloud.google.com/go/spanner/internal/version.go
index 3f0621322..1a70149b3 100644
--- a/vendor/cloud.google.com/go/spanner/internal/version.go
+++ b/vendor/cloud.google.com/go/spanner/internal/version.go
@@ -15,4 +15,4 @@
package internal
// Version is the current tagged release of the library.
-const Version = "1.60.0"
+const Version = "1.67.0"
diff --git a/vendor/cloud.google.com/go/spanner/key.go b/vendor/cloud.google.com/go/spanner/key.go
index e6ecfe444..26b1d9ba9 100644
--- a/vendor/cloud.google.com/go/spanner/key.go
+++ b/vendor/cloud.google.com/go/spanner/key.go
@@ -24,8 +24,9 @@ import (
"cloud.google.com/go/civil"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
- proto3 "github.com/golang/protobuf/ptypes/struct"
"google.golang.org/grpc/codes"
+ "google.golang.org/protobuf/reflect/protoreflect"
+ proto3 "google.golang.org/protobuf/types/known/structpb"
)
// A Key can be either a Cloud Spanner row's primary key or a secondary index
@@ -58,6 +59,7 @@ import (
// - string and NullString are mapped to Cloud Spanner's STRING type.
// - time.Time and NullTime are mapped to Cloud Spanner's TIMESTAMP type.
// - civil.Date and NullDate are mapped to Cloud Spanner's DATE type.
+// - protoreflect.Enum and NullProtoEnum are mapped to Cloud Spanner's ENUM type.
type Key []interface{}
// errInvdKeyPartType returns error for unsupported key part type.
@@ -83,7 +85,7 @@ func keyPartValue(part interface{}) (pb *proto3.Value, err error) {
pb, _, err = encodeValue(int64(v))
case uint32:
pb, _, err = encodeValue(int64(v))
- case int64, float64, float32, NullInt64, NullFloat64, NullFloat32, bool, NullBool, []byte, string, NullString, time.Time, civil.Date, NullTime, NullDate, big.Rat, NullNumeric:
+ case int64, float64, float32, NullInt64, NullFloat64, NullFloat32, bool, NullBool, []byte, string, NullString, time.Time, civil.Date, NullTime, NullDate, big.Rat, NullNumeric, protoreflect.Enum, NullProtoEnum:
pb, _, err = encodeValue(v)
case Encoder:
part, err = v.EncodeSpanner()
@@ -138,7 +140,7 @@ func (key Key) String() string {
func (key Key) elemString(b *bytes.Buffer, part interface{}) {
switch v := part.(type) {
- case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, float32, float64, bool:
+ case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, float32, float64, bool, protoreflect.Enum:
// Use %v to print numeric types and bool.
fmt.Fprintf(b, "%v", v)
case string:
@@ -149,7 +151,7 @@ func (key Key) elemString(b *bytes.Buffer, part interface{}) {
} else {
fmt.Fprint(b, nullString)
}
- case NullInt64, NullFloat64, NullBool, NullNumeric:
+ case NullInt64, NullFloat64, NullBool, NullNumeric, NullProtoEnum:
// The above types implement fmt.Stringer.
fmt.Fprintf(b, "%s", v)
case NullString, NullDate, NullTime:
diff --git a/vendor/cloud.google.com/go/spanner/mutation.go b/vendor/cloud.google.com/go/spanner/mutation.go
index eb9baba7b..b9909742d 100644
--- a/vendor/cloud.google.com/go/spanner/mutation.go
+++ b/vendor/cloud.google.com/go/spanner/mutation.go
@@ -20,8 +20,8 @@ import (
"reflect"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
- proto3 "github.com/golang/protobuf/ptypes/struct"
"google.golang.org/grpc/codes"
+ proto3 "google.golang.org/protobuf/types/known/structpb"
)
// op is the mutation operation.
diff --git a/vendor/cloud.google.com/go/spanner/ot_metrics.go b/vendor/cloud.google.com/go/spanner/ot_metrics.go
index 2f49cadec..16190860c 100644
--- a/vendor/cloud.google.com/go/spanner/ot_metrics.go
+++ b/vendor/cloud.google.com/go/spanner/ot_metrics.go
@@ -33,12 +33,13 @@ const OtInstrumentationScope = "cloud.google.com/go"
const metricsPrefix = "spanner/"
var (
- attributeKeyClientID = attribute.Key("client_id")
- attributeKeyDatabase = attribute.Key("database")
- attributeKeyInstance = attribute.Key("instance_id")
- attributeKeyLibVersion = attribute.Key("library_version")
- attributeKeyType = attribute.Key("type")
- attributeKeyMethod = attribute.Key("grpc_client_method")
+ attributeKeyClientID = attribute.Key("client_id")
+ attributeKeyDatabase = attribute.Key("database")
+ attributeKeyInstance = attribute.Key("instance_id")
+ attributeKeyLibVersion = attribute.Key("library_version")
+ attributeKeyType = attribute.Key("type")
+ attributeKeyMethod = attribute.Key("grpc_client_method")
+ attributeKeyIsMultiplexed = attribute.Key("is_multiplexed")
attributeNumInUseSessions = attributeKeyType.String("num_in_use_sessions")
attributeNumSessions = attributeKeyType.String("num_sessions")
@@ -69,6 +70,12 @@ func createOpenTelemetryConfig(mp metric.MeterProvider, logger *log.Logger, sess
}
config.attributeMap = append(config.attributeMap, attributeMap...)
+ config.attributeMapWithMultiplexed = append(config.attributeMapWithMultiplexed, attributeMap...)
+ config.attributeMapWithMultiplexed = append(config.attributeMapWithMultiplexed, attributeKeyIsMultiplexed.String("true"))
+
+ config.attributeMapWithoutMultiplexed = append(config.attributeMapWithoutMultiplexed, attributeMap...)
+ config.attributeMapWithoutMultiplexed = append(config.attributeMapWithoutMultiplexed, attributeKeyIsMultiplexed.String("false"))
+
setOpenTelemetryMetricProvider(config, mp, logger)
return config, nil
}
@@ -197,13 +204,14 @@ func registerSessionPoolOTMetrics(pool *sessionPool) error {
func(ctx context.Context, o metric.Observer) error {
pool.mu.Lock()
defer pool.mu.Unlock()
-
+ if pool.multiplexedSession != nil {
+ o.ObserveInt64(otConfig.openSessionCount, int64(1), metric.WithAttributes(otConfig.attributeMapWithMultiplexed...))
+ }
o.ObserveInt64(otConfig.openSessionCount, int64(pool.numOpened), metric.WithAttributes(attributes...))
o.ObserveInt64(otConfig.maxAllowedSessionsCount, int64(pool.SessionPoolConfig.MaxOpened), metric.WithAttributes(attributes...))
- o.ObserveInt64(otConfig.sessionsCount, int64(pool.numInUse), metric.WithAttributes(attributesInUseSessions...))
+ o.ObserveInt64(otConfig.sessionsCount, int64(pool.numInUse), metric.WithAttributes(append(attributesInUseSessions, attribute.Key("is_multiplexed").String("false"))...))
o.ObserveInt64(otConfig.sessionsCount, int64(pool.numSessions), metric.WithAttributes(attributesAvailableSessions...))
- o.ObserveInt64(otConfig.maxInUseSessionsCount, int64(pool.maxNumInUse), metric.WithAttributes(attributes...))
-
+ o.ObserveInt64(otConfig.maxInUseSessionsCount, int64(pool.maxNumInUse), metric.WithAttributes(append(attributes, attribute.Key("is_multiplexed").String("false"))...))
return nil
},
otConfig.openSessionCount,
diff --git a/vendor/cloud.google.com/go/spanner/pdml.go b/vendor/cloud.google.com/go/spanner/pdml.go
index ac3b5b0fe..bb33ef291 100644
--- a/vendor/cloud.google.com/go/spanner/pdml.go
+++ b/vendor/cloud.google.com/go/spanner/pdml.go
@@ -84,7 +84,7 @@ func (c *Client) partitionedUpdate(ctx context.Context, statement Statement, opt
// Execute the PDML and retry if the transaction is aborted.
executePdmlWithRetry := func(ctx context.Context) (int64, error) {
for {
- count, err := executePdml(contextWithOutgoingMetadata(ctx, sh.getMetadata(), c.disableRouteToLeader), sh, req)
+ count, err := executePdml(contextWithOutgoingMetadata(ctx, sh.getMetadata(), c.disableRouteToLeader), sh, req, options)
if err == nil {
return count, nil
}
@@ -106,14 +106,15 @@ func (c *Client) partitionedUpdate(ctx context.Context, statement Statement, opt
// 3. Execute the update statement on the PDML transaction
//
// Note that PDML transactions cannot be committed or rolled back.
-func executePdml(ctx context.Context, sh *sessionHandle, req *sppb.ExecuteSqlRequest) (count int64, err error) {
+func executePdml(ctx context.Context, sh *sessionHandle, req *sppb.ExecuteSqlRequest, options QueryOptions) (count int64, err error) {
var md metadata.MD
sh.updateLastUseTime()
// Begin transaction.
res, err := sh.getClient().BeginTransaction(ctx, &sppb.BeginTransactionRequest{
Session: sh.getID(),
Options: &sppb.TransactionOptions{
- Mode: &sppb.TransactionOptions_PartitionedDml_{PartitionedDml: &sppb.TransactionOptions_PartitionedDml{}},
+ Mode: &sppb.TransactionOptions_PartitionedDml_{PartitionedDml: &sppb.TransactionOptions_PartitionedDml{}},
+ ExcludeTxnFromChangeStreams: options.ExcludeTxnFromChangeStreams,
},
})
if err != nil {
diff --git a/vendor/cloud.google.com/go/spanner/protoutils.go b/vendor/cloud.google.com/go/spanner/protoutils.go
index 83af997ca..988e71594 100644
--- a/vendor/cloud.google.com/go/spanner/protoutils.go
+++ b/vendor/cloud.google.com/go/spanner/protoutils.go
@@ -24,7 +24,9 @@ import (
"cloud.google.com/go/civil"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
- proto3 "github.com/golang/protobuf/ptypes/struct"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
+ proto3 "google.golang.org/protobuf/types/known/structpb"
)
// Helpers to generate protobuf values and Cloud Spanner types.
@@ -85,6 +87,10 @@ func pgNumericType() *sppb.Type {
return &sppb.Type{Code: sppb.TypeCode_NUMERIC, TypeAnnotation: sppb.TypeAnnotationCode_PG_NUMERIC}
}
+func pgOidType() *sppb.Type {
+ return &sppb.Type{Code: sppb.TypeCode_INT64, TypeAnnotation: sppb.TypeAnnotationCode_PG_OID}
+}
+
func jsonType() *sppb.Type {
return &sppb.Type{Code: sppb.TypeCode_JSON}
}
@@ -140,3 +146,20 @@ func structType(fields ...*sppb.StructType_Field) *sppb.Type {
func nullProto() *proto3.Value {
return &proto3.Value{Kind: &proto3.Value_NullValue{NullValue: proto3.NullValue_NULL_VALUE}}
}
+
+func protoMessageType(fqn string) *sppb.Type {
+ return &sppb.Type{Code: sppb.TypeCode_PROTO, ProtoTypeFqn: fqn}
+}
+
+func protoEnumType(fqn string) *sppb.Type {
+ return &sppb.Type{Code: sppb.TypeCode_ENUM, ProtoTypeFqn: fqn}
+}
+
+func protoMessageProto(m proto.Message) *proto3.Value {
+ var b, _ = proto.Marshal(m)
+ return &proto3.Value{Kind: &proto3.Value_StringValue{StringValue: base64.StdEncoding.EncodeToString(b)}}
+}
+
+func protoEnumProto(e protoreflect.Enum) *proto3.Value {
+ return &proto3.Value{Kind: &proto3.Value_StringValue{StringValue: strconv.FormatInt(int64(e.Number()), 10)}}
+}
diff --git a/vendor/cloud.google.com/go/spanner/read.go b/vendor/cloud.google.com/go/spanner/read.go
index 50578b740..83755722e 100644
--- a/vendor/cloud.google.com/go/spanner/read.go
+++ b/vendor/cloud.google.com/go/spanner/read.go
@@ -27,11 +27,11 @@ import (
"cloud.google.com/go/internal/protostruct"
"cloud.google.com/go/internal/trace"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
- "github.com/golang/protobuf/proto"
- proto3 "github.com/golang/protobuf/ptypes/struct"
"github.com/googleapis/gax-go/v2"
"google.golang.org/api/iterator"
"google.golang.org/grpc/codes"
+ "google.golang.org/protobuf/proto"
+ proto3 "google.golang.org/protobuf/types/known/structpb"
)
// streamingReceiver is the interface for receiving data from a client side
@@ -498,7 +498,7 @@ var (
)
func (d *resumableStreamDecoder) next() bool {
- retryer := onCodes(d.backoff, codes.Unavailable, codes.Internal)
+ retryer := onCodes(d.backoff, codes.Unavailable, codes.ResourceExhausted, codes.Internal)
for {
switch d.state {
case unConnected:
diff --git a/vendor/cloud.google.com/go/spanner/retry.go b/vendor/cloud.google.com/go/spanner/retry.go
index 752e8933e..a140ce62e 100644
--- a/vendor/cloud.google.com/go/spanner/retry.go
+++ b/vendor/cloud.google.com/go/spanner/retry.go
@@ -22,7 +22,6 @@ import (
"time"
"cloud.google.com/go/internal/trace"
- "github.com/golang/protobuf/ptypes"
"github.com/googleapis/gax-go/v2"
"google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/grpc/codes"
@@ -86,7 +85,7 @@ func (r *spannerRetryer) Retry(err error) (time.Duration, bool) {
// a minimum of 10ms and maximum of 32s. There is no delay before the retry if
// the error was Session not found or failed inline begin transaction.
func runWithRetryOnAbortedOrFailedInlineBeginOrSessionNotFound(ctx context.Context, f func(context.Context) error) error {
- retryer := onCodes(DefaultRetryBackoff, codes.Aborted, codes.Internal)
+ retryer := onCodes(DefaultRetryBackoff, codes.Aborted, codes.ResourceExhausted, codes.Internal)
funcWithRetry := func(ctx context.Context) error {
for {
err := f(ctx)
@@ -147,11 +146,10 @@ func ExtractRetryDelay(err error) (time.Duration, bool) {
}
for _, detail := range s.Details() {
if retryInfo, ok := detail.(*errdetails.RetryInfo); ok {
- delay, err := ptypes.Duration(retryInfo.RetryDelay)
- if err != nil {
+ if !retryInfo.GetRetryDelay().IsValid() {
return 0, false
}
- return delay, true
+ return retryInfo.GetRetryDelay().AsDuration(), true
}
}
return 0, false
diff --git a/vendor/cloud.google.com/go/spanner/row.go b/vendor/cloud.google.com/go/spanner/row.go
index 5905bc9b2..f61350435 100644
--- a/vendor/cloud.google.com/go/spanner/row.go
+++ b/vendor/cloud.google.com/go/spanner/row.go
@@ -22,8 +22,8 @@ import (
"strings"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
- proto3 "github.com/golang/protobuf/ptypes/struct"
"google.golang.org/grpc/codes"
+ proto3 "google.golang.org/protobuf/types/known/structpb"
)
// A Row is a view of a row of data returned by a Cloud Spanner read.
diff --git a/vendor/cloud.google.com/go/spanner/session.go b/vendor/cloud.google.com/go/spanner/session.go
index a201b5ff5..3e587095a 100644
--- a/vendor/cloud.google.com/go/spanner/session.go
+++ b/vendor/cloud.google.com/go/spanner/session.go
@@ -24,6 +24,7 @@ import (
"log"
"math"
"math/rand"
+ "os"
"runtime/debug"
"strings"
"sync"
@@ -36,12 +37,16 @@ import (
"go.opencensus.io/stats"
"go.opencensus.io/tag"
octrace "go.opencensus.io/trace"
+ "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
)
-const healthCheckIntervalMins = 50
+const (
+ healthCheckIntervalMins = 50
+ multiplexSessionRefreshInterval = 7 * 24 * time.Hour
+)
// ActionOnInactiveTransactionKind describes the kind of action taken when there are inactive transactions.
type ActionOnInactiveTransactionKind int
@@ -85,6 +90,8 @@ type sessionHandle struct {
// session is a pointer to a session object. Transactions never need to
// access it directly.
session *session
+ // client is the RPC channel to Cloud Spanner. It is set only once during session acquisition.
+ client *vkit.Client
// checkoutTime is the time the session was checked out of the pool.
checkoutTime time.Time
// lastUseTime is the time the session was last used after checked out of the pool.
@@ -115,6 +122,7 @@ func (sh *sessionHandle) recycle() {
tracked := sh.trackedSessionHandle
s := sh.session
sh.session = nil
+ sh.client = nil
sh.trackedSessionHandle = nil
sh.checkoutTime = time.Time{}
sh.lastUseTime = time.Time{}
@@ -149,6 +157,10 @@ func (sh *sessionHandle) getClient() *vkit.Client {
if sh.session == nil {
return nil
}
+ if sh.client != nil {
+ // Use the gRPC connection from the session handle
+ return sh.client
+ }
return sh.session.client
}
@@ -185,6 +197,7 @@ func (sh *sessionHandle) destroy() {
}
tracked := sh.trackedSessionHandle
sh.session = nil
+ sh.client = nil
sh.trackedSessionHandle = nil
sh.checkoutTime = time.Time{}
sh.lastUseTime = time.Time{}
@@ -197,7 +210,8 @@ func (sh *sessionHandle) destroy() {
p.trackedSessionHandles.Remove(tracked)
p.mu.Unlock()
}
- s.destroy(false)
+ // since sessionHandle is always used by Transactions we can safely destroy the session with wasInUse=true
+ s.destroy(false, true)
}
func (sh *sessionHandle) updateLastUseTime() {
@@ -252,6 +266,8 @@ type session struct {
tx transactionID
// firstHCDone indicates whether the first health check is done or not.
firstHCDone bool
+ // isMultiplexed is true if the session is multiplexed.
+ isMultiplexed bool
}
// isValid returns true if the session is still valid for use.
@@ -370,11 +386,16 @@ func (s *session) getNextCheck() time.Time {
func (s *session) recycle() {
s.setTransactionID(nil)
s.pool.mu.Lock()
+ if s.isMultiplexed {
+ s.pool.decNumMultiplexedInUseLocked(context.Background())
+ s.pool.mu.Unlock()
+ return
+ }
if !s.pool.recycleLocked(s) {
// s is rejected by its home session pool because it expired and the
// session pool currently has enough open sessions.
s.pool.mu.Unlock()
- s.destroy(false)
+ s.destroy(false, true)
s.pool.mu.Lock()
}
s.pool.decNumInUseLocked(context.Background())
@@ -383,15 +404,15 @@ func (s *session) recycle() {
// destroy removes the session from its home session pool, healthcheck queue
// and Cloud Spanner service.
-func (s *session) destroy(isExpire bool) bool {
+func (s *session) destroy(isExpire, wasInUse bool) bool {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
- return s.destroyWithContext(ctx, isExpire)
+ return s.destroyWithContext(ctx, isExpire, wasInUse)
}
-func (s *session) destroyWithContext(ctx context.Context, isExpire bool) bool {
+func (s *session) destroyWithContext(ctx context.Context, isExpire, wasInUse bool) bool {
// Remove s from session pool.
- if !s.pool.remove(s, isExpire) {
+ if !s.pool.remove(s, isExpire, wasInUse) {
return false
}
// Unregister s from healthcheck queue.
@@ -475,6 +496,11 @@ type SessionPoolConfig struct {
// Defaults to 50m.
HealthCheckInterval time.Duration
+ // MultiplexSessionCheckInterval is the interval at which the multiplexed session is checked whether it needs to be refreshed.
+ //
+ // Defaults to 10 mins.
+ MultiplexSessionCheckInterval time.Duration
+
// TrackSessionHandles determines whether the session pool will keep track
// of the stacktrace of the goroutines that take sessions from the pool.
// This setting can be used to track down session leak problems.
@@ -554,6 +580,11 @@ func (spc *SessionPoolConfig) validate() error {
return nil
}
+type muxSessionCreateRequest struct {
+ ctx context.Context
+ force bool
+}
+
// sessionPool creates and caches Cloud Spanner sessions.
type sessionPool struct {
// mu protects sessionPool from concurrent access.
@@ -569,12 +600,25 @@ type sessionPool struct {
// idleList caches idle session IDs. Session IDs in this list can be
// allocated for use.
idleList list.List
+ // multiplexSessionClientCounter is the counter for the multiplexed session client.
+ multiplexSessionClientCounter int
+ // clientPool is a pool of Cloud Spanner grpc clients.
+ clientPool []*vkit.Client
+ // multiplexedSession contains the multiplexed session
+ multiplexedSession *session
// mayGetSession is for broadcasting that session retrival/creation may
// proceed.
mayGetSession chan struct{}
+ // multiplexedSessionReq is the ongoing multiplexed session creation request (if any).
+ multiplexedSessionReq chan muxSessionCreateRequest
+ // mayGetMultiplexedSession is for broadcasting that multiplexed session retrieval is possible.
+ mayGetMultiplexedSession chan bool
// sessionCreationError is the last error that occurred during session
// creation and is propagated to any waiters waiting for a session.
sessionCreationError error
+ // multiplexedSessionCreationError is the error that occurred during multiplexed session
+ // creation for the first time and is propagated to any waiters waiting for a session.
+ multiplexedSessionCreationError error
// numOpened is the total number of open sessions from the session pool.
numOpened uint64
// createReqs is the number of ongoing session creation requests.
@@ -616,6 +660,9 @@ type sessionPool struct {
numOfLeakedSessionsRemoved uint64
otConfig *openTelemetryConfig
+
+ // enableMultiplexSession is a flag to enable multiplexed session.
+ enableMultiplexSession bool
}
// newSessionPool creates a new session pool.
@@ -650,15 +697,24 @@ func newSessionPool(sc *sessionClient, config SessionPoolConfig) (*sessionPool,
if config.usedSessionsRatioThreshold == 0 {
config.usedSessionsRatioThreshold = DefaultSessionPoolConfig.usedSessionsRatioThreshold
}
-
+ if config.MultiplexSessionCheckInterval == 0 {
+ config.MultiplexSessionCheckInterval = 10 * time.Minute
+ }
+ isMultiplexed := strings.ToLower(os.Getenv("GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS"))
+ if isMultiplexed != "" && isMultiplexed != "true" && isMultiplexed != "false" {
+ return nil, spannerErrorf(codes.InvalidArgument, "GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS must be either true or false")
+ }
pool := &sessionPool{
- sc: sc,
- valid: true,
- mayGetSession: make(chan struct{}),
- SessionPoolConfig: config,
- mw: newMaintenanceWindow(config.MaxOpened),
- rand: rand.New(rand.NewSource(time.Now().UnixNano())),
- otConfig: sc.otConfig,
+ sc: sc,
+ valid: true,
+ mayGetSession: make(chan struct{}),
+ mayGetMultiplexedSession: make(chan bool),
+ multiplexedSessionReq: make(chan muxSessionCreateRequest),
+ SessionPoolConfig: config,
+ mw: newMaintenanceWindow(config.MaxOpened),
+ rand: rand.New(rand.NewSource(time.Now().UnixNano())),
+ otConfig: sc.otConfig,
+ enableMultiplexSession: isMultiplexed == "true",
}
_, instance, database, err := parseDatabaseName(sc.database)
@@ -681,7 +737,7 @@ func newSessionPool(sc *sessionClient, config SessionPoolConfig) (*sessionPool,
// 10ms to finish, given a 5 minutes interval and 10 healthcheck workers, a
// healthChecker can effectively mantain
// 100 checks_per_worker/sec * 10 workers * 300 seconds = 300K sessions.
- pool.hc = newHealthChecker(config.HealthCheckInterval, config.HealthCheckWorkers, config.healthCheckSampleInterval, pool)
+ pool.hc = newHealthChecker(config.HealthCheckInterval, config.MultiplexSessionCheckInterval, config.HealthCheckWorkers, config.healthCheckSampleInterval, pool)
// First initialize the pool before we indicate that the healthchecker is
// ready. This prevents the maintainer from starting before the pool has
@@ -693,6 +749,22 @@ func newSessionPool(sc *sessionClient, config SessionPoolConfig) (*sessionPool,
return nil, err
}
}
+ if pool.enableMultiplexSession {
+ go pool.createMultiplexedSession()
+ ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
+ pool.multiplexedSessionReq <- muxSessionCreateRequest{force: true, ctx: ctx}
+ // listen for the session to be created
+ go func() {
+ select {
+ case <-ctx.Done():
+ cancel()
+ return
+ // wait for the session to be created
+ case <-pool.mayGetMultiplexedSession:
+ }
+ return
+ }()
+ }
pool.recordStat(context.Background(), MaxAllowedSessionsCount, int64(config.MaxOpened))
err = registerSessionPoolOTMetrics(pool)
@@ -717,9 +789,17 @@ func (p *sessionPool) recordStat(ctx context.Context, m *stats.Int64Measure, n i
recordStat(ctx, m, n)
}
-func (p *sessionPool) recordOTStat(ctx context.Context, m metric.Int64Counter, val int64) {
+type recordOTStatOption struct {
+ attr []attribute.KeyValue
+}
+
+func (p *sessionPool) recordOTStat(ctx context.Context, m metric.Int64Counter, val int64, option recordOTStatOption) {
if m != nil {
- m.Add(ctx, val, metric.WithAttributes(p.otConfig.attributeMap...))
+ attrs := p.otConfig.attributeMap
+ if len(option.attr) > 0 {
+ attrs = option.attr
+ }
+ m.Add(ctx, val, metric.WithAttributes(attrs...))
}
}
@@ -746,7 +826,7 @@ func (p *sessionPool) getLongRunningSessionsLocked() []*sessionHandle {
element = element.Next()
continue
}
- diff := time.Now().Sub(sh.lastUseTime)
+ diff := time.Since(sh.lastUseTime)
if !sh.eligibleForLongRunning && diff.Seconds() >= p.idleTimeThreshold.Seconds() {
if (p.ActionOnInactiveTransaction == Warn || p.ActionOnInactiveTransaction == WarnAndClose) && !sh.isSessionLeakLogged {
if p.ActionOnInactiveTransaction == Warn {
@@ -812,13 +892,57 @@ func (p *sessionPool) growPoolLocked(numSessions uint64, distributeOverChannels
return p.sc.batchCreateSessions(int32(numSessions), distributeOverChannels, p)
}
+func (p *sessionPool) createMultiplexedSession() {
+ for c := range p.multiplexedSessionReq {
+ p.mu.Lock()
+ sess := p.multiplexedSession
+ p.mu.Unlock()
+ if c.force || sess == nil {
+ p.mu.Lock()
+ p.sc.mu.Lock()
+ client, err := p.sc.nextClient()
+ p.sc.mu.Unlock()
+ p.mu.Unlock()
+ if err != nil {
+ // If we can't get a client, we can't create a session.
+ p.mu.Lock()
+ p.multiplexedSessionCreationError = err
+ p.mu.Unlock()
+ p.mayGetMultiplexedSession <- true
+ continue
+ }
+ p.sc.executeCreateMultiplexedSession(c.ctx, client, p.sc.md, p)
+ continue
+ }
+ select {
+ case p.mayGetMultiplexedSession <- true:
+ case <-c.ctx.Done():
+ return
+ }
+ }
+}
+
// sessionReady is executed by the SessionClient when a session has been
// created and is ready to use. This method will add the new session to the
// pool and decrease the number of sessions that is being created.
-func (p *sessionPool) sessionReady(s *session) {
+func (p *sessionPool) sessionReady(ctx context.Context, s *session) {
p.mu.Lock()
defer p.mu.Unlock()
// Clear any session creation error.
+ if s.isMultiplexed {
+ s.pool = p
+ p.multiplexedSession = s
+ p.multiplexedSessionCreationError = nil
+ p.recordStat(context.Background(), OpenSessionCount, int64(1), tag.Tag{Key: tagKeyIsMultiplexed, Value: "true"})
+ p.recordStat(context.Background(), SessionsCount, 1, tagNumSessions, tag.Tag{Key: tagKeyIsMultiplexed, Value: "true"})
+ // either notify the waiting goroutine or skip if no one is waiting
+ select {
+ case p.mayGetMultiplexedSession <- true:
+ case <-ctx.Done():
+ return
+ }
+ return
+ }
p.sessionCreationError = nil
// Set this pool as the home pool of the session and register it with the
// health checker.
@@ -848,12 +972,32 @@ func (p *sessionPool) sessionReady(s *session) {
// or more requested sessions finished with an error. sessionCreationFailed will
// decrease the number of sessions being created and notify any waiters that
// the session creation failed.
-func (p *sessionPool) sessionCreationFailed(err error, numSessions int32) {
+func (p *sessionPool) sessionCreationFailed(ctx context.Context, err error, numSessions int32, isMultiplexed bool) {
p.mu.Lock()
defer p.mu.Unlock()
+ if isMultiplexed {
+ // Ignore the error if multiplexed session already present
+ if p.multiplexedSession != nil {
+ p.multiplexedSessionCreationError = nil
+ select {
+ case p.mayGetMultiplexedSession <- true:
+ case <-ctx.Done():
+ return
+ }
+ return
+ }
+ p.recordStat(context.Background(), OpenSessionCount, int64(0), tag.Tag{Key: tagKeyIsMultiplexed, Value: "true"})
+ p.multiplexedSessionCreationError = err
+ select {
+ case p.mayGetMultiplexedSession <- true:
+ case <-ctx.Done():
+ return
+ }
+ return
+ }
p.createReqs -= uint64(numSessions)
p.numOpened -= uint64(numSessions)
- p.recordStat(context.Background(), OpenSessionCount, int64(p.numOpened))
+ p.recordStat(context.Background(), OpenSessionCount, int64(p.numOpened), tag.Tag{Key: tagKeyIsMultiplexed, Value: "false"})
// Notify other waiters blocking on session creation.
p.sessionCreationError = err
close(p.mayGetSession)
@@ -900,14 +1044,14 @@ func (p *sessionPool) close(ctx context.Context) {
wg := sync.WaitGroup{}
for _, s := range allSessions {
wg.Add(1)
- go deleteSession(ctx, s, &wg)
+ go closeSession(ctx, s, &wg)
}
wg.Wait()
}
-func deleteSession(ctx context.Context, s *session, wg *sync.WaitGroup) {
+func closeSession(ctx context.Context, s *session, wg *sync.WaitGroup) {
defer wg.Done()
- s.destroyWithContext(ctx, false)
+ s.destroyWithContext(ctx, false, false)
}
// errInvalidSessionPool is the error for using an invalid session pool.
@@ -923,19 +1067,46 @@ var errGetSessionTimeout = spannerErrorf(codes.Canceled, "timeout / context canc
// sessions being checked out of the pool.
func (p *sessionPool) newSessionHandle(s *session) (sh *sessionHandle) {
sh = &sessionHandle{session: s, checkoutTime: time.Now(), lastUseTime: time.Now()}
+ if s.isMultiplexed {
+ p.mu.Lock()
+ sh.client = p.getRoundRobinClient()
+ p.mu.Unlock()
+ return sh
+ }
if p.TrackSessionHandles || p.ActionOnInactiveTransaction == Warn || p.ActionOnInactiveTransaction == WarnAndClose || p.ActionOnInactiveTransaction == Close {
p.mu.Lock()
sh.trackedSessionHandle = p.trackedSessionHandles.PushBack(sh)
- p.mu.Unlock()
if p.TrackSessionHandles {
sh.stack = debug.Stack()
}
+ p.mu.Unlock()
}
return sh
}
+func (p *sessionPool) getRoundRobinClient() *vkit.Client {
+ p.sc.mu.Lock()
+ defer func() {
+ p.multiplexSessionClientCounter++
+ p.sc.mu.Unlock()
+ }()
+ if len(p.clientPool) == 0 {
+ p.clientPool = make([]*vkit.Client, p.sc.connPool.Num())
+ for i := 0; i < p.sc.connPool.Num(); i++ {
+ c, err := p.sc.nextClient()
+ if err != nil {
+ // If we can't get a client, use the session's client.
+ return nil
+ }
+ p.clientPool[i] = c
+ }
+ }
+ p.multiplexSessionClientCounter = p.multiplexSessionClientCounter % len(p.clientPool)
+ return p.clientPool[p.multiplexSessionClientCounter]
+}
+
// errGetSessionTimeout returns error for context timeout during
-// sessionPool.take().
+// sessionPool.take() or sessionPool.takeMultiplexed().
func (p *sessionPool) errGetSessionTimeout(ctx context.Context) error {
var code codes.Code
if ctx.Err() == context.DeadlineExceeded {
@@ -987,42 +1158,11 @@ func (p *sessionPool) getTrackedSessionHandleStacksLocked() string {
return stackTraces
}
-func (p *sessionPool) createSession(ctx context.Context) (*session, error) {
- trace.TracePrintf(ctx, nil, "Creating a new session")
- doneCreate := func(done bool) {
- p.mu.Lock()
- if !done {
- // Session creation failed, give budget back.
- p.numOpened--
- p.recordStat(ctx, OpenSessionCount, int64(p.numOpened))
- }
- p.createReqs--
- // Notify other waiters blocking on session creation.
- close(p.mayGetSession)
- p.mayGetSession = make(chan struct{})
- p.mu.Unlock()
- }
- s, err := p.sc.createSession(ctx)
- if err != nil {
- doneCreate(false)
- // Should return error directly because of the previous retries on
- // CreateSession RPC.
- // If the error is a timeout, there is a chance that the session was
- // created on the server but is not known to the session pool. This
- // session will then be garbage collected by the server after 1 hour.
- return nil, err
- }
- s.pool = p
- p.hc.register(s)
- doneCreate(true)
- return s, nil
-}
-
func (p *sessionPool) isHealthy(s *session) bool {
if s.getNextCheck().Add(2 * p.hc.getInterval()).Before(time.Now()) {
if err := s.ping(); isSessionNotFoundError(err) {
// The session is already bad, continue to fetch/create a new one.
- s.destroy(false)
+ s.destroy(false, false)
return false
}
p.hc.scheduledHC(s)
@@ -1084,9 +1224,9 @@ func (p *sessionPool) take(ctx context.Context) (*sessionHandle, error) {
select {
case <-ctx.Done():
trace.TracePrintf(ctx, nil, "Context done waiting for session")
- p.recordStat(ctx, GetSessionTimeoutsCount, 1)
+ p.recordStat(ctx, GetSessionTimeoutsCount, 1, tag.Tag{Key: tagKeyIsMultiplexed, Value: "false"})
if p.otConfig != nil {
- p.recordOTStat(ctx, p.otConfig.getSessionTimeoutsCount, 1)
+ p.recordOTStat(ctx, p.otConfig.getSessionTimeoutsCount, 1, recordOTStatOption{attr: p.otConfig.attributeMapWithoutMultiplexed})
}
p.mu.Lock()
p.numWaiters--
@@ -1106,6 +1246,63 @@ func (p *sessionPool) take(ctx context.Context) (*sessionHandle, error) {
}
}
+// takeMultiplexed returns a cached session if there is available one; if there isn't
+// any, it tries to allocate a new one.
+func (p *sessionPool) takeMultiplexed(ctx context.Context) (*sessionHandle, error) {
+ trace.TracePrintf(ctx, nil, "Acquiring a multiplexed session")
+ for {
+ var s *session
+ p.mu.Lock()
+ if !p.valid {
+ p.mu.Unlock()
+ return nil, errInvalidSessionPool
+ }
+ if !p.enableMultiplexSession {
+ p.mu.Unlock()
+ return p.take(ctx)
+ }
+ // use the multiplex session if it is available
+ if p.multiplexedSession != nil {
+ // Multiplexed session is available, get it.
+ s = p.multiplexedSession
+ trace.TracePrintf(ctx, map[string]interface{}{"sessionID": s.getID()},
+ "Acquired multiplexed session")
+ p.mu.Unlock()
+ p.incNumMultiplexedInUse(ctx)
+ return p.newSessionHandle(s), nil
+ }
+ mayGetSession := p.mayGetMultiplexedSession
+ p.mu.Unlock()
+ p.multiplexedSessionReq <- muxSessionCreateRequest{force: false, ctx: ctx}
+ select {
+ case <-ctx.Done():
+ trace.TracePrintf(ctx, nil, "Context done waiting for multiplexed session")
+ p.recordStat(ctx, GetSessionTimeoutsCount, 1, tag.Tag{Key: tagKeyIsMultiplexed, Value: "true"})
+ if p.otConfig != nil {
+ p.recordOTStat(ctx, p.otConfig.getSessionTimeoutsCount, 1, recordOTStatOption{attr: p.otConfig.attributeMapWithMultiplexed})
+ }
+ return nil, p.errGetSessionTimeout(ctx)
+ case <-mayGetSession: // Block until multiplexed session is created.
+ p.mu.Lock()
+ if p.multiplexedSessionCreationError != nil {
+ trace.TracePrintf(ctx, nil, "Error creating multiplexed session: %v", p.multiplexedSessionCreationError)
+ err := p.multiplexedSessionCreationError
+ if isUnimplementedError(err) {
+ logf(p.sc.logger, "Multiplexed session is not enabled on this project, continuing with regular sessions")
+ p.enableMultiplexSession = false
+ } else {
+ p.mu.Unlock()
+ // If the error is a timeout, there is a chance that the session was
+ // created on the server but is not known to the session pool. In this
+ // case, we should retry to get the session.
+ return nil, err
+ }
+ }
+ p.mu.Unlock()
+ }
+ }
+}
+
// recycle puts session s back to the session pool's idle list, it returns true
// if the session pool successfully recycles session s.
func (p *sessionPool) recycle(s *session) bool {
@@ -1133,7 +1330,10 @@ func (p *sessionPool) recycleLocked(s *session) bool {
// remove atomically removes session s from the session pool and invalidates s.
// If isExpire == true, the removal is triggered by session expiration and in
// such cases, only idle sessions can be removed.
-func (p *sessionPool) remove(s *session, isExpire bool) bool {
+func (p *sessionPool) remove(s *session, isExpire bool, wasInUse bool) bool {
+ if s.isMultiplexed {
+ return false
+ }
p.mu.Lock()
defer p.mu.Unlock()
if isExpire && (p.numOpened <= p.MinOpened || s.getIdleList() == nil) {
@@ -1141,6 +1341,7 @@ func (p *sessionPool) remove(s *session, isExpire bool) bool {
// if number of open sessions is going below p.MinOpened.
return false
}
+
ol := s.setIdleList(nil)
ctx := context.Background()
// If the session is in the idlelist, remove it.
@@ -1152,10 +1353,11 @@ func (p *sessionPool) remove(s *session, isExpire bool) bool {
if s.invalidate() {
// Decrease the number of opened sessions.
p.numOpened--
- // Decrease the number of sessions in use.
- p.decNumInUseLocked(ctx)
+ // Decrease the number of sessions in use, only when not from idle list.
+ if wasInUse {
+ p.decNumInUseLocked(ctx)
+ }
p.recordStat(ctx, OpenSessionCount, int64(p.numOpened))
- // Broadcast that a session has been destroyed.
close(p.mayGetSession)
p.mayGetSession = make(chan struct{})
return true
@@ -1175,23 +1377,42 @@ func (p *sessionPool) incNumInUse(ctx context.Context) {
func (p *sessionPool) incNumInUseLocked(ctx context.Context) {
p.numInUse++
- p.recordStat(ctx, SessionsCount, int64(p.numInUse), tagNumInUseSessions)
- p.recordStat(ctx, AcquiredSessionsCount, 1)
+ p.recordStat(ctx, SessionsCount, int64(p.numInUse), tagNumInUseSessions, tag.Tag{Key: tagKeyIsMultiplexed, Value: "false"})
+ p.recordStat(ctx, AcquiredSessionsCount, 1, tag.Tag{Key: tagKeyIsMultiplexed, Value: "false"})
if p.otConfig != nil {
- p.recordOTStat(ctx, p.otConfig.acquiredSessionsCount, 1)
+ p.recordOTStat(ctx, p.otConfig.acquiredSessionsCount, 1, recordOTStatOption{attr: p.otConfig.attributeMapWithoutMultiplexed})
}
if p.numInUse > p.maxNumInUse {
p.maxNumInUse = p.numInUse
- p.recordStat(ctx, MaxInUseSessionsCount, int64(p.maxNumInUse))
+ p.recordStat(ctx, MaxInUseSessionsCount, int64(p.maxNumInUse), tag.Tag{Key: tagKeyIsMultiplexed, Value: "false"})
+ }
+}
+
+func (p *sessionPool) incNumMultiplexedInUse(ctx context.Context) {
+ p.recordStat(ctx, AcquiredSessionsCount, 1, tag.Tag{Key: tagKeyIsMultiplexed, Value: "true"})
+ if p.otConfig != nil {
+ p.recordOTStat(ctx, p.otConfig.acquiredSessionsCount, 1, recordOTStatOption{attr: p.otConfig.attributeMapWithMultiplexed})
}
}
func (p *sessionPool) decNumInUseLocked(ctx context.Context) {
p.numInUse--
- p.recordStat(ctx, SessionsCount, int64(p.numInUse), tagNumInUseSessions)
- p.recordStat(ctx, ReleasedSessionsCount, 1)
+ if int64(p.numInUse) < 0 {
+ // print whole call stack trace
+ logf(p.sc.logger, "Number of sessions in use is negative, resetting it to currSessionsCheckedOutLocked. Stack trace: %s", string(debug.Stack()))
+ p.numInUse = p.currSessionsCheckedOutLocked()
+ }
+ p.recordStat(ctx, SessionsCount, int64(p.numInUse), tagNumInUseSessions, tag.Tag{Key: tagKeyIsMultiplexed, Value: "false"})
+ p.recordStat(ctx, ReleasedSessionsCount, 1, tag.Tag{Key: tagKeyIsMultiplexed, Value: "false"})
+ if p.otConfig != nil {
+ p.recordOTStat(ctx, p.otConfig.releasedSessionsCount, 1, recordOTStatOption{attr: p.otConfig.attributeMapWithoutMultiplexed})
+ }
+}
+
+func (p *sessionPool) decNumMultiplexedInUseLocked(ctx context.Context) {
+ p.recordStat(ctx, ReleasedSessionsCount, 1, tag.Tag{Key: tagKeyIsMultiplexed, Value: "true"})
if p.otConfig != nil {
- p.recordOTStat(ctx, p.otConfig.releasedSessionsCount, 1)
+ p.recordOTStat(ctx, p.otConfig.releasedSessionsCount, 1, recordOTStatOption{attr: p.otConfig.attributeMapWithMultiplexed})
}
}
@@ -1334,6 +1555,8 @@ type healthChecker struct {
pool *sessionPool
// sampleInterval is the interval of sampling by the maintainer.
sampleInterval time.Duration
+ // multiplexSessionRefreshInterval is the interval of refreshing multiplexed session.
+ multiplexSessionRefreshInterval time.Duration
// ready is used to signal that maintainer can start running.
ready chan struct{}
// done is used to signal that health checker should be closed.
@@ -1344,18 +1567,19 @@ type healthChecker struct {
}
// newHealthChecker initializes new instance of healthChecker.
-func newHealthChecker(interval time.Duration, workers int, sampleInterval time.Duration, pool *sessionPool) *healthChecker {
+func newHealthChecker(interval, multiplexSessionRefreshInterval time.Duration, workers int, sampleInterval time.Duration, pool *sessionPool) *healthChecker {
if workers <= 0 {
workers = 1
}
hc := &healthChecker{
- interval: interval,
- workers: workers,
- pool: pool,
- sampleInterval: sampleInterval,
- ready: make(chan struct{}),
- done: make(chan struct{}),
- maintainerCancel: func() {},
+ interval: interval,
+ multiplexSessionRefreshInterval: multiplexSessionRefreshInterval,
+ workers: workers,
+ pool: pool,
+ sampleInterval: sampleInterval,
+ ready: make(chan struct{}),
+ done: make(chan struct{}),
+ maintainerCancel: func() {},
}
hc.waitWorkers.Add(1)
go hc.maintainer()
@@ -1363,6 +1587,9 @@ func newHealthChecker(interval time.Duration, workers int, sampleInterval time.D
hc.waitWorkers.Add(1)
go hc.worker(i)
}
+ if hc.pool.enableMultiplexSession {
+ go hc.multiplexSessionWorker()
+ }
return hc
}
@@ -1454,14 +1681,17 @@ func (hc *healthChecker) markDone(s *session) {
// healthCheck checks the health of the session and pings it if needed.
func (hc *healthChecker) healthCheck(s *session) {
defer hc.markDone(s)
+ if s.isMultiplexed {
+ return
+ }
if !s.pool.isValid() {
// Session pool is closed, perform a garbage collection.
- s.destroy(false)
+ s.destroy(false, false)
return
}
if err := s.ping(); isSessionNotFoundError(err) {
// Ping failed, destroy the session.
- s.destroy(false)
+ s.destroy(false, false)
}
}
@@ -1543,7 +1773,7 @@ func (hc *healthChecker) maintainer() {
now := time.Now()
if now.After(hc.pool.lastResetTime.Add(10 * time.Minute)) {
hc.pool.maxNumInUse = hc.pool.numInUse
- hc.pool.recordStat(context.Background(), MaxInUseSessionsCount, int64(hc.pool.maxNumInUse))
+ hc.pool.recordStat(context.Background(), MaxInUseSessionsCount, int64(hc.pool.maxNumInUse), tag.Tag{Key: tagKeyIsMultiplexed, Value: "false"})
hc.pool.lastResetTime = now
}
hc.pool.mu.Unlock()
@@ -1643,13 +1873,43 @@ func (hc *healthChecker) shrinkPool(ctx context.Context, shrinkToNumSessions uin
if s != nil {
deleted++
// destroy session as expire.
- s.destroy(true)
+ s.destroy(true, false)
} else {
break
}
}
}
+func (hc *healthChecker) multiplexSessionWorker() {
+ for {
+ if hc.isClosing() {
+ return
+ }
+ hc.pool.mu.Lock()
+ createTime := time.Now()
+ s := hc.pool.multiplexedSession
+ if s != nil {
+ createTime = hc.pool.multiplexedSession.createTime
+ }
+ hc.pool.mu.Unlock()
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+ if createTime.Add(multiplexSessionRefreshInterval).Before(time.Now()) {
+ // Multiplexed session is idle for more than 7 days, replace it.
+ hc.pool.multiplexedSessionReq <- muxSessionCreateRequest{force: true, ctx: ctx}
+ // wait for the new multiplexed session to be created.
+ <-hc.pool.mayGetMultiplexedSession
+ }
+ // Sleep for a while to avoid burning CPU.
+ select {
+ case <-time.After(hc.multiplexSessionRefreshInterval):
+ cancel()
+ case <-hc.done:
+ cancel()
+ return
+ }
+ }
+}
+
// maxUint64 returns the maximum of two uint64.
func maxUint64(a, b uint64) uint64 {
if a > b {
@@ -1683,6 +1943,17 @@ func isSessionNotFoundError(err error) bool {
return strings.Contains(err.Error(), "Session not found")
}
+// isUnimplementedError returns true if the gRPC error code is Unimplemented.
+func isUnimplementedError(err error) bool {
+ if err == nil {
+ return false
+ }
+ if ErrCode(err) == codes.Unimplemented {
+ return true
+ }
+ return false
+}
+
func isFailedInlineBeginTransaction(err error) bool {
if err == nil {
return false
diff --git a/vendor/cloud.google.com/go/spanner/sessionclient.go b/vendor/cloud.google.com/go/spanner/sessionclient.go
index edbf82a80..e0a56f9af 100644
--- a/vendor/cloud.google.com/go/spanner/sessionclient.go
+++ b/vendor/cloud.google.com/go/spanner/sessionclient.go
@@ -71,13 +71,13 @@ func (cg *clientIDGenerator) nextID(database string) string {
type sessionConsumer interface {
// sessionReady is called when a session has been created and is ready for
// use.
- sessionReady(s *session)
+ sessionReady(ctx context.Context, s *session)
// sessionCreationFailed is called when the creation of a sub-batch of
// sessions failed. The numSessions argument specifies the number of
// sessions that could not be created as a result of this error. A
// consumer may receive multiple errors per batch.
- sessionCreationFailed(err error, numSessions int32)
+ sessionCreationFailed(ctx context.Context, err error, numSessions int32, isMultiplexed bool)
}
// sessionClient creates sessions for a database, either in batches or one at a
@@ -254,12 +254,12 @@ func (sc *sessionClient) executeBatchCreateSessions(client *vkit.Client, createC
if closed {
err := spannerErrorf(codes.Canceled, "Session client closed")
trace.TracePrintf(ctx, nil, "Session client closed while creating a batch of %d sessions: %v", createCount, err)
- consumer.sessionCreationFailed(err, remainingCreateCount)
+ consumer.sessionCreationFailed(ctx, err, remainingCreateCount, false)
break
}
if ctx.Err() != nil {
trace.TracePrintf(ctx, nil, "Context error while creating a batch of %d sessions: %v", createCount, ctx.Err())
- consumer.sessionCreationFailed(ToSpannerError(ctx.Err()), remainingCreateCount)
+ consumer.sessionCreationFailed(ctx, ToSpannerError(ctx.Err()), remainingCreateCount, false)
break
}
var mdForGFELatency metadata.MD
@@ -294,13 +294,13 @@ func (sc *sessionClient) executeBatchCreateSessions(client *vkit.Client, createC
}
if err != nil {
trace.TracePrintf(ctx, nil, "Error creating a batch of %d sessions: %v", remainingCreateCount, err)
- consumer.sessionCreationFailed(ToSpannerError(err), remainingCreateCount)
+ consumer.sessionCreationFailed(ctx, ToSpannerError(err), remainingCreateCount, false)
break
}
actuallyCreated := int32(len(response.Session))
trace.TracePrintf(ctx, nil, "Received a batch of %d sessions", actuallyCreated)
for _, s := range response.Session {
- consumer.sessionReady(&session{valid: true, client: client, id: s.Name, createTime: time.Now(), md: md, logger: sc.logger})
+ consumer.sessionReady(ctx, &session{valid: true, client: client, id: s.Name, createTime: time.Now(), md: md, logger: sc.logger})
}
if actuallyCreated < remainingCreateCount {
// Spanner could return less sessions than requested. In that case, we
@@ -313,6 +313,62 @@ func (sc *sessionClient) executeBatchCreateSessions(client *vkit.Client, createC
}
}
+func (sc *sessionClient) executeCreateMultiplexedSession(ctx context.Context, client *vkit.Client, md metadata.MD, consumer sessionConsumer) {
+ ctx = trace.StartSpan(ctx, "cloud.google.com/go/spanner.CreateSession")
+ defer func() { trace.EndSpan(ctx, nil) }()
+ trace.TracePrintf(ctx, nil, "Creating a multiplexed session")
+ sc.mu.Lock()
+ closed := sc.closed
+ sc.mu.Unlock()
+ if closed {
+ err := spannerErrorf(codes.Canceled, "Session client closed")
+ trace.TracePrintf(ctx, nil, "Session client closed while creating a multiplexed session: %v", err)
+ return
+ }
+ if ctx.Err() != nil {
+ trace.TracePrintf(ctx, nil, "Context error while creating a multiplexed session: %v", ctx.Err())
+ consumer.sessionCreationFailed(ctx, ToSpannerError(ctx.Err()), 1, true)
+ return
+ }
+ var mdForGFELatency metadata.MD
+ response, err := client.CreateSession(contextWithOutgoingMetadata(ctx, sc.md, sc.disableRouteToLeader), &sppb.CreateSessionRequest{
+ Database: sc.database,
+ // Multiplexed sessions do not support labels.
+ Session: &sppb.Session{CreatorRole: sc.databaseRole, Multiplexed: true},
+ }, gax.WithGRPCOptions(grpc.Header(&mdForGFELatency)))
+
+ if getGFELatencyMetricsFlag() && mdForGFELatency != nil {
+ _, instance, database, err := parseDatabaseName(sc.database)
+ if err != nil {
+ trace.TracePrintf(ctx, nil, "Error getting instance and database name: %v", err)
+ }
+ // Errors should not prevent initializing the session pool.
+ ctxGFE, err := tag.New(ctx,
+ tag.Upsert(tagKeyClientID, sc.id),
+ tag.Upsert(tagKeyDatabase, database),
+ tag.Upsert(tagKeyInstance, instance),
+ tag.Upsert(tagKeyLibVersion, internal.Version),
+ )
+ if err != nil {
+ trace.TracePrintf(ctx, nil, "Error in adding tags in CreateSession for GFE Latency: %v", err)
+ }
+ err = captureGFELatencyStats(ctxGFE, mdForGFELatency, "executeCreateSession")
+ if err != nil {
+ trace.TracePrintf(ctx, nil, "Error in Capturing GFE Latency and Header Missing count. Try disabling and rerunning. Error: %v", err)
+ }
+ }
+ if metricErr := recordGFELatencyMetricsOT(ctx, mdForGFELatency, "executeCreateSession", sc.otConfig); metricErr != nil {
+ trace.TracePrintf(ctx, nil, "Error in recording GFE Latency through OpenTelemetry. Error: %v", metricErr)
+ }
+ if err != nil {
+ trace.TracePrintf(ctx, nil, "Error creating a multiplexed sessions: %v", err)
+ consumer.sessionCreationFailed(ctx, ToSpannerError(err), 1, true)
+ return
+ }
+ consumer.sessionReady(ctx, &session{valid: true, client: client, id: response.Name, createTime: time.Now(), md: md, logger: sc.logger, isMultiplexed: response.Multiplexed})
+ trace.TracePrintf(ctx, nil, "Finished creating multiplexed sessions")
+}
+
func (sc *sessionClient) sessionWithID(id string) (*session, error) {
sc.mu.Lock()
defer sc.mu.Unlock()
@@ -328,9 +384,15 @@ func (sc *sessionClient) sessionWithID(id string) (*session, error) {
// session. Using the same channel for all gRPC calls for a session ensures the
// optimal usage of server side caches.
func (sc *sessionClient) nextClient() (*vkit.Client, error) {
- // This call should never return an error as we are passing in an existing
- // connection, so we can safely ignore it.
- client, err := vkit.NewClient(context.Background(), option.WithGRPCConn(sc.connPool.Conn()))
+ var clientOpt option.ClientOption
+ if _, ok := sc.connPool.(*gmeWrapper); ok {
+ // Pass GCPMultiEndpoint as a pool.
+ clientOpt = gtransport.WithConnPool(sc.connPool)
+ } else {
+ // Pick a grpc.ClientConn from a regular pool.
+ clientOpt = option.WithGRPCConn(sc.connPool.Conn())
+ }
+ client, err := vkit.NewClient(context.Background(), clientOpt)
if err != nil {
return nil, err
}
diff --git a/vendor/cloud.google.com/go/spanner/statement.go b/vendor/cloud.google.com/go/spanner/statement.go
index f08af2e77..407036312 100644
--- a/vendor/cloud.google.com/go/spanner/statement.go
+++ b/vendor/cloud.google.com/go/spanner/statement.go
@@ -20,9 +20,9 @@ import (
"fmt"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
- proto3 "github.com/golang/protobuf/ptypes/struct"
- structpb "github.com/golang/protobuf/ptypes/struct"
"google.golang.org/grpc/codes"
+ proto3 "google.golang.org/protobuf/types/known/structpb"
+ structpb "google.golang.org/protobuf/types/known/structpb"
)
// A Statement is a SQL query with named parameters.
diff --git a/vendor/cloud.google.com/go/spanner/stats.go b/vendor/cloud.google.com/go/spanner/stats.go
index 8e77ecf3d..bc8176b6d 100644
--- a/vendor/cloud.google.com/go/spanner/stats.go
+++ b/vendor/cloud.google.com/go/spanner/stats.go
@@ -31,12 +31,14 @@ const statsPrefix = "cloud.google.com/go/spanner/"
// Deprecated: OpenCensus project is deprecated. Use OpenTelemetry for capturing metrics.
var (
- tagKeyClientID = tag.MustNewKey("client_id")
- tagKeyDatabase = tag.MustNewKey("database")
- tagKeyInstance = tag.MustNewKey("instance_id")
- tagKeyLibVersion = tag.MustNewKey("library_version")
- tagKeyType = tag.MustNewKey("type")
- tagCommonKeys = []tag.Key{tagKeyClientID, tagKeyDatabase, tagKeyInstance, tagKeyLibVersion}
+ tagKeyClientID = tag.MustNewKey("client_id")
+ tagKeyDatabase = tag.MustNewKey("database")
+ tagKeyInstance = tag.MustNewKey("instance_id")
+ tagKeyLibVersion = tag.MustNewKey("library_version")
+ tagKeyType = tag.MustNewKey("type")
+ tagKeyIsMultiplexed = tag.MustNewKey("is_multiplexed")
+
+ tagCommonKeys = []tag.Key{tagKeyClientID, tagKeyDatabase, tagKeyInstance, tagKeyLibVersion}
tagNumInUseSessions = tag.Tag{Key: tagKeyType, Value: "num_in_use_sessions"}
tagNumSessions = tag.Tag{Key: tagKeyType, Value: "num_sessions"}
diff --git a/vendor/cloud.google.com/go/spanner/timestampbound.go b/vendor/cloud.google.com/go/spanner/timestampbound.go
index f488b2994..00a1396a1 100644
--- a/vendor/cloud.google.com/go/spanner/timestampbound.go
+++ b/vendor/cloud.google.com/go/spanner/timestampbound.go
@@ -21,8 +21,8 @@ import (
"time"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
- pbd "github.com/golang/protobuf/ptypes/duration"
- pbt "github.com/golang/protobuf/ptypes/timestamp"
+ pbd "google.golang.org/protobuf/types/known/durationpb"
+ pbt "google.golang.org/protobuf/types/known/timestamppb"
)
// timestampBoundType specifies the timestamp bound mode.
diff --git a/vendor/cloud.google.com/go/spanner/transaction.go b/vendor/cloud.google.com/go/spanner/transaction.go
index 79427e782..f251adca1 100644
--- a/vendor/cloud.google.com/go/spanner/transaction.go
+++ b/vendor/cloud.google.com/go/spanner/transaction.go
@@ -24,13 +24,13 @@ import (
"cloud.google.com/go/internal/trace"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
- "github.com/golang/protobuf/proto"
"github.com/googleapis/gax-go/v2"
"google.golang.org/api/iterator"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
+ "google.golang.org/protobuf/proto"
vkit "cloud.google.com/go/spanner/apiv1"
durationpb "google.golang.org/protobuf/types/known/durationpb"
@@ -115,15 +115,20 @@ type TransactionOptions struct {
// the transaction lock mode is used to specify a concurrency mode for the
// read/query operations. It works for a read/write transaction only.
ReadLockMode sppb.TransactionOptions_ReadWrite_ReadLockMode
+
+ // Controls whether to exclude recording modifications in current transaction
+ // from the allowed tracking change streams(with DDL option allow_txn_exclusion=true).
+ ExcludeTxnFromChangeStreams bool
}
// merge combines two TransactionOptions that the input parameter will have higher
// order of precedence.
func (to TransactionOptions) merge(opts TransactionOptions) TransactionOptions {
merged := TransactionOptions{
- CommitOptions: to.CommitOptions.merge(opts.CommitOptions),
- TransactionTag: to.TransactionTag,
- CommitPriority: to.CommitPriority,
+ CommitOptions: to.CommitOptions.merge(opts.CommitOptions),
+ TransactionTag: to.TransactionTag,
+ CommitPriority: to.CommitPriority,
+ ExcludeTxnFromChangeStreams: to.ExcludeTxnFromChangeStreams || opts.ExcludeTxnFromChangeStreams,
}
if opts.TransactionTag != "" {
merged.TransactionTag = opts.TransactionTag
@@ -177,6 +182,13 @@ type ReadOptions struct {
// ReadOptions option used to set the DirectedReadOptions for all ReadRequests which indicate
// which replicas or regions should be used for running read operations.
DirectedReadOptions *sppb.DirectedReadOptions
+
+ // An option to control the order in which rows are returned from a read.
+ OrderBy sppb.ReadRequest_OrderBy
+
+ // A lock hint mechanism to use for this request. This setting is only applicable for
+ // read-write transaction as as read-only transactions do not take locks.
+ LockHint sppb.ReadRequest_LockHint
}
// merge combines two ReadOptions that the input parameter will have higher
@@ -189,6 +201,8 @@ func (ro ReadOptions) merge(opts ReadOptions) ReadOptions {
RequestTag: ro.RequestTag,
DataBoostEnabled: ro.DataBoostEnabled,
DirectedReadOptions: ro.DirectedReadOptions,
+ OrderBy: ro.OrderBy,
+ LockHint: ro.LockHint,
}
if opts.Index != "" {
merged.Index = opts.Index
@@ -208,6 +222,12 @@ func (ro ReadOptions) merge(opts ReadOptions) ReadOptions {
if opts.DirectedReadOptions != nil {
merged.DirectedReadOptions = opts.DirectedReadOptions
}
+ if opts.OrderBy != sppb.ReadRequest_ORDER_BY_UNSPECIFIED {
+ merged.OrderBy = opts.OrderBy
+ }
+ if opts.LockHint != sppb.ReadRequest_LOCK_HINT_UNSPECIFIED {
+ merged.LockHint = opts.LockHint
+ }
return merged
}
@@ -240,6 +260,8 @@ func (t *txReadOnly) ReadWithOptions(ctx context.Context, table string, keys Key
requestTag := t.ro.RequestTag
dataBoostEnabled := t.ro.DataBoostEnabled
directedReadOptions := t.ro.DirectedReadOptions
+ orderBy := t.ro.OrderBy
+ lockHint := t.ro.LockHint
if opts != nil {
index = opts.Index
if opts.Limit > 0 {
@@ -253,6 +275,13 @@ func (t *txReadOnly) ReadWithOptions(ctx context.Context, table string, keys Key
if opts.DirectedReadOptions != nil {
directedReadOptions = opts.DirectedReadOptions
}
+ if opts.OrderBy != sppb.ReadRequest_ORDER_BY_UNSPECIFIED {
+ orderBy = opts.OrderBy
+ }
+ if opts.LockHint != sppb.ReadRequest_LOCK_HINT_UNSPECIFIED {
+ lockHint = opts.LockHint
+ }
+
}
var setTransactionID func(transactionID)
if _, ok := ts.Selector.(*sppb.TransactionSelector_Begin); ok {
@@ -280,6 +309,8 @@ func (t *txReadOnly) ReadWithOptions(ctx context.Context, table string, keys Key
RequestOptions: createRequestOptions(prio, requestTag, t.txOpts.TransactionTag),
DataBoostEnabled: dataBoostEnabled,
DirectedReadOptions: directedReadOptions,
+ OrderBy: orderBy,
+ LockHint: lockHint,
})
if err != nil {
if _, ok := t.getTransactionSelector().GetSelector().(*sppb.TransactionSelector_Begin); ok {
@@ -309,12 +340,16 @@ func (t *txReadOnly) ReadWithOptions(ctx context.Context, table string, keys Key
// errRowNotFound returns error for not being able to read the row identified by
// key.
func errRowNotFound(table string, key Key) error {
- return spannerErrorf(codes.NotFound, "row not found(Table: %v, PrimaryKey: %v)", table, key)
+ err := spannerErrorf(codes.NotFound, "row not found(Table: %v, PrimaryKey: %v)", table, key)
+ err.(*Error).err = ErrRowNotFound
+ return err
}
// errRowNotFoundByIndex returns error for not being able to read the row by index.
func errRowNotFoundByIndex(table string, key Key, index string) error {
- return spannerErrorf(codes.NotFound, "row not found(Table: %v, IndexKey: %v, Index: %v)", table, key, index)
+ err := spannerErrorf(codes.NotFound, "row not found(Table: %v, IndexKey: %v, Index: %v)", table, key, index)
+ err.(*Error).err = ErrRowNotFound
+ return err
}
// errMultipleRowsFound returns error for receiving more than one row when reading a single row using an index.
@@ -329,8 +364,14 @@ func errInlineBeginTransactionFailed() error {
// ReadRow reads a single row from the database.
//
-// If no row is present with the given key, then ReadRow returns an error where
+// If no row is present with the given key, then ReadRow returns an error(spanner.ErrRowNotFound) where
// spanner.ErrCode(err) is codes.NotFound.
+//
+// To check if the error is spanner.ErrRowNotFound:
+//
+// if errors.Is(err, spanner.ErrRowNotFound) {
+// ...
+// }
func (t *txReadOnly) ReadRow(ctx context.Context, table string, key Key, columns []string) (*Row, error) {
return t.ReadRowWithOptions(ctx, table, key, columns, nil)
}
@@ -339,6 +380,12 @@ func (t *txReadOnly) ReadRow(ctx context.Context, table string, key Key, columns
//
// If no row is present with the given key, then ReadRowWithOptions returns an error where
// spanner.ErrCode(err) is codes.NotFound.
+//
+// To check if the error is spanner.ErrRowNotFound:
+//
+// if errors.Is(err, spanner.ErrRowNotFound) {
+// ...
+// }
func (t *txReadOnly) ReadRowWithOptions(ctx context.Context, table string, key Key, columns []string, opts *ReadOptions) (*Row, error) {
iter := t.ReadWithOptions(ctx, table, key, columns, opts)
defer iter.Stop()
@@ -356,7 +403,13 @@ func (t *txReadOnly) ReadRowWithOptions(ctx context.Context, table string, key K
// ReadRowUsingIndex reads a single row from the database using an index.
//
// If no row is present with the given index, then ReadRowUsingIndex returns an
-// error where spanner.ErrCode(err) is codes.NotFound.
+// error(spanner.ErrRowNotFound) where spanner.ErrCode(err) is codes.NotFound.
+//
+// To check if the error is spanner.ErrRowNotFound:
+//
+// if errors.Is(err, spanner.ErrRowNotFound) {
+// ...
+// }
//
// If more than one row received with the given index, then ReadRowUsingIndex
// returns an error where spanner.ErrCode(err) is codes.FailedPrecondition.
@@ -401,18 +454,24 @@ type QueryOptions struct {
// QueryOptions option used to set the DirectedReadOptions for all ExecuteSqlRequests which indicate
// which replicas or regions should be used for executing queries.
DirectedReadOptions *sppb.DirectedReadOptions
+
+ // Controls whether to exclude recording modifications in current partitioned update operation
+ // from the allowed tracking change streams(with DDL option allow_txn_exclusion=true). Setting
+ // this value for any sql/dml requests other than partitioned udpate will receive an error.
+ ExcludeTxnFromChangeStreams bool
}
// merge combines two QueryOptions that the input parameter will have higher
// order of precedence.
func (qo QueryOptions) merge(opts QueryOptions) QueryOptions {
merged := QueryOptions{
- Mode: qo.Mode,
- Options: &sppb.ExecuteSqlRequest_QueryOptions{},
- RequestTag: qo.RequestTag,
- Priority: qo.Priority,
- DataBoostEnabled: qo.DataBoostEnabled,
- DirectedReadOptions: qo.DirectedReadOptions,
+ Mode: qo.Mode,
+ Options: &sppb.ExecuteSqlRequest_QueryOptions{},
+ RequestTag: qo.RequestTag,
+ Priority: qo.Priority,
+ DataBoostEnabled: qo.DataBoostEnabled,
+ DirectedReadOptions: qo.DirectedReadOptions,
+ ExcludeTxnFromChangeStreams: qo.ExcludeTxnFromChangeStreams || opts.ExcludeTxnFromChangeStreams,
}
if opts.Mode != nil {
merged.Mode = opts.Mode
@@ -622,6 +681,13 @@ func errUnexpectedTxState(ts txState) error {
return spannerErrorf(codes.FailedPrecondition, "unexpected transaction state: %v", ts)
}
+// errExcludeRequestLevelDmlFromChangeStreams returns error for passing
+// QueryOptions.ExcludeTxnFromChangeStreams to request-level DML functions. This
+// options should only be used for partitioned update.
+func errExcludeRequestLevelDmlFromChangeStreams() error {
+ return spannerErrorf(codes.InvalidArgument, "cannot set exclude transaction from change streams for a request-level DML statement.")
+}
+
// ReadOnlyTransaction provides a snapshot transaction with guaranteed
// consistency across reads, but does not allow writes. Read-only transactions
// can be configured to read at timestamps in the past.
@@ -710,7 +776,7 @@ func (t *ReadOnlyTransaction) begin(ctx context.Context) error {
}()
// Retry the BeginTransaction call if a 'Session not found' is returned.
for {
- sh, err = t.sp.take(ctx)
+ sh, err = t.sp.takeMultiplexed(ctx)
if err != nil {
return err
}
@@ -800,7 +866,7 @@ func (t *ReadOnlyTransaction) acquireSingleUse(ctx context.Context) (*sessionHan
},
},
}
- sh, err := t.sp.take(ctx)
+ sh, err := t.sp.takeMultiplexed(ctx)
if err != nil {
return nil, nil, err
}
@@ -1104,6 +1170,10 @@ func (t *ReadWriteTransaction) Update(ctx context.Context, stmt Statement) (rowC
// the number of affected rows. The given QueryOptions will be used for the
// execution of this statement.
func (t *ReadWriteTransaction) UpdateWithOptions(ctx context.Context, stmt Statement, opts QueryOptions) (rowCount int64, err error) {
+ if opts.ExcludeTxnFromChangeStreams {
+ return 0, errExcludeRequestLevelDmlFromChangeStreams()
+ }
+
return t.update(ctx, stmt, t.qo.merge(opts))
}
@@ -1176,6 +1246,9 @@ func (t *ReadWriteTransaction) BatchUpdate(ctx context.Context, stmts []Statemen
// The request tag and priority given in the QueryOptions are included with the
// RPC. Any other options that are set in the QueryOptions struct are ignored.
func (t *ReadWriteTransaction) BatchUpdateWithOptions(ctx context.Context, stmts []Statement, opts QueryOptions) (_ []int64, err error) {
+ if opts.ExcludeTxnFromChangeStreams {
+ return nil, errExcludeRequestLevelDmlFromChangeStreams()
+ }
return t.batchUpdateWithOptions(ctx, stmts, t.qo.merge(opts))
}
@@ -1296,6 +1369,7 @@ func (t *ReadWriteTransaction) acquire(ctx context.Context) (*sessionHandle, *sp
Mode: &sppb.TransactionOptions_ReadWrite_{
ReadWrite: &sppb.TransactionOptions_ReadWrite{},
},
+ ExcludeTxnFromChangeStreams: t.txOpts.ExcludeTxnFromChangeStreams,
},
},
}
@@ -1355,6 +1429,7 @@ func (t *ReadWriteTransaction) getTransactionSelector() *sppb.TransactionSelecto
ReadLockMode: t.txOpts.ReadLockMode,
},
},
+ ExcludeTxnFromChangeStreams: t.txOpts.ExcludeTxnFromChangeStreams,
},
},
}
@@ -1411,6 +1486,7 @@ func beginTransaction(ctx context.Context, sid string, client *vkit.Client, opts
ReadLockMode: opts.ReadLockMode,
},
},
+ ExcludeTxnFromChangeStreams: opts.ExcludeTxnFromChangeStreams,
},
})
if err != nil {
@@ -1716,6 +1792,7 @@ func NewReadWriteStmtBasedTransactionWithOptions(ctx context.Context, c *Client,
txReadyOrClosed: make(chan struct{}),
},
}
+ t.txReadOnly.sp = c.idleSessions
t.txReadOnly.sh = sh
t.txReadOnly.txReadEnv = t
t.txReadOnly.qo = c.qo
@@ -1778,6 +1855,12 @@ type writeOnlyTransaction struct {
commitPriority sppb.RequestOptions_Priority
// disableRouteToLeader specifies if we want to disable RW/PDML requests to be routed to leader.
disableRouteToLeader bool
+ // ExcludeTxnFromChangeStreams controls whether to exclude recording modifications in
+ // current transaction from the allowed tracking change streams with DDL option
+ // allow_txn_exclusion=true.
+ excludeTxnFromChangeStreams bool
+ // commitOptions are applied to the Commit request for the writeOnlyTransaction..
+ commitOptions CommitOptions
}
// applyAtLeastOnce commits a list of mutations to Cloud Spanner at least once,
@@ -1802,6 +1885,11 @@ func (t *writeOnlyTransaction) applyAtLeastOnce(ctx context.Context, ms ...*Muta
return ts, err
}
+ var maxCommitDelay *durationpb.Duration
+ if t.commitOptions.MaxCommitDelay != nil {
+ maxCommitDelay = durationpb.New(*(t.commitOptions.MaxCommitDelay))
+ }
+
// Make a retryer for Aborted and certain Internal errors.
retryer := onCodes(DefaultRetryBackoff, codes.Aborted, codes.Internal)
// Apply the mutation and retry if the commit is aborted.
@@ -1809,7 +1897,7 @@ func (t *writeOnlyTransaction) applyAtLeastOnce(ctx context.Context, ms ...*Muta
for {
if sh == nil || sh.getID() == "" || sh.getClient() == nil {
// No usable session for doing the commit, take one from pool.
- sh, err = t.sp.take(ctx)
+ sh, err = t.sp.takeMultiplexed(ctx)
if err != nil {
// sessionPool.Take already retries for session
// creations/retrivals.
@@ -1824,12 +1912,15 @@ func (t *writeOnlyTransaction) applyAtLeastOnce(ctx context.Context, ms ...*Muta
Mode: &sppb.TransactionOptions_ReadWrite_{
ReadWrite: &sppb.TransactionOptions_ReadWrite{},
},
+ ExcludeTxnFromChangeStreams: t.excludeTxnFromChangeStreams,
},
},
Mutations: mPb,
RequestOptions: createRequestOptions(t.commitPriority, "", t.transactionTag),
+ MaxCommitDelay: maxCommitDelay,
})
if err != nil && !isAbortedErr(err) {
+ // should not be the case with multiplexed sessions
if isSessionNotFoundError(err) {
// Discard the bad session.
sh.destroy()
diff --git a/vendor/cloud.google.com/go/spanner/value.go b/vendor/cloud.google.com/go/spanner/value.go
index 1d4e4ea67..b25867874 100644
--- a/vendor/cloud.google.com/go/spanner/value.go
+++ b/vendor/cloud.google.com/go/spanner/value.go
@@ -21,6 +21,7 @@ import (
"database/sql"
"database/sql/driver"
"encoding/base64"
+ "encoding/json"
"fmt"
"math"
"math/big"
@@ -32,10 +33,11 @@ import (
"cloud.google.com/go/civil"
"cloud.google.com/go/internal/fields"
sppb "cloud.google.com/go/spanner/apiv1/spannerpb"
- "github.com/golang/protobuf/proto"
- proto3 "github.com/golang/protobuf/ptypes/struct"
- jsoniter "github.com/json-iterator/go"
"google.golang.org/grpc/codes"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/protoadapt"
+ "google.golang.org/protobuf/reflect/protoreflect"
+ proto3 "google.golang.org/protobuf/types/known/structpb"
)
const (
@@ -114,7 +116,10 @@ var (
jsonNullBytes = []byte("null")
- jsonProvider = jsoniter.ConfigCompatibleWithStandardLibrary
+ jsonUseNumber bool
+
+ protoMsgReflectType = reflect.TypeOf((*proto.Message)(nil)).Elem()
+ protoEnumReflectType = reflect.TypeOf((*protoreflect.Enum)(nil)).Elem()
)
// UseNumberWithJSONDecoderEncoder specifies whether Cloud Spanner JSON numbers are decoded
@@ -124,11 +129,15 @@ var (
// NOTE 1: Calling this method affects the behavior of all clients created by this library, both existing and future instances.
// NOTE 2: This method sets a global variable that is used by the client to encode/decode JSON numbers. Access to the global variable is not synchronized. You should only call this method when there are no goroutines encoding/decoding Cloud Spanner JSON values. It is recommended to only call this method during the initialization of your application, and preferably before you create any Cloud Spanner clients, and/or in tests when there are no queries being executed.
func UseNumberWithJSONDecoderEncoder(useNumber bool) {
- jsonProvider = jsoniter.Config{
- EscapeHTML: true,
- SortMapKeys: true, // Sort map keys to ensure deterministic output, to be consistent with encoding.
- UseNumber: useNumber,
- }.Froze()
+ jsonUseNumber = useNumber
+}
+
+func jsonUnmarshal(data []byte, v any) error {
+ dec := json.NewDecoder(bytes.NewReader(data))
+ if jsonUseNumber {
+ dec.UseNumber()
+ }
+ return dec.Decode(v)
}
// Encoder is the interface implemented by a custom type that can be encoded to
@@ -297,7 +306,7 @@ func (n *NullString) UnmarshalJSON(payload []byte) error {
return nil
}
var s *string
- if err := jsonProvider.Unmarshal(payload, &s); err != nil {
+ if err := jsonUnmarshal(payload, &s); err != nil {
return err
}
if s != nil {
@@ -866,7 +875,7 @@ func (n NullJSON) String() string {
if !n.Valid {
return nullString
}
- b, err := jsonProvider.Marshal(n.Value)
+ b, err := json.Marshal(n.Value)
if err != nil {
return fmt.Sprintf("error: %v", err)
}
@@ -888,7 +897,7 @@ func (n *NullJSON) UnmarshalJSON(payload []byte) error {
return nil
}
var v interface{}
- err := jsonProvider.Unmarshal(payload, &v)
+ err := jsonUnmarshal(payload, &v)
if err != nil {
return fmt.Errorf("payload cannot be converted to a struct: got %v, err: %w", string(payload), err)
}
@@ -945,6 +954,102 @@ func (n *PGNumeric) UnmarshalJSON(payload []byte) error {
return nil
}
+// NullProtoMessage represents a Cloud Spanner PROTO that may be NULL.
+// To write a NULL value using NullProtoMessage set ProtoMessageVal to typed nil and set Valid to true.
+type NullProtoMessage struct {
+ ProtoMessageVal proto.Message // ProtoMessageVal contains the value when Valid is true, and nil when NULL.
+ Valid bool // Valid is true if ProtoMessageVal is not NULL.
+}
+
+// IsNull implements NullableValue.IsNull for NullProtoMessage.
+func (n NullProtoMessage) IsNull() bool {
+ return !n.Valid
+}
+
+// String implements Stringer.String for NullProtoMessage.
+func (n NullProtoMessage) String() string {
+ if !n.Valid {
+ return nullString
+ }
+ return protoadapt.MessageV1Of(n.ProtoMessageVal).String()
+}
+
+// MarshalJSON implements json.Marshaler.MarshalJSON for NullProtoMessage.
+func (n NullProtoMessage) MarshalJSON() ([]byte, error) {
+ if n.Valid {
+ return json.Marshal(n.ProtoMessageVal)
+ }
+ return jsonNullBytes, nil
+}
+
+// UnmarshalJSON implements json.Unmarshaler.UnmarshalJSON for NullProtoMessage.
+func (n *NullProtoMessage) UnmarshalJSON(payload []byte) error {
+ if payload == nil {
+ return fmt.Errorf("payload should not be nil")
+ }
+ if bytes.Equal(payload, jsonNullBytes) {
+ n.ProtoMessageVal = nil
+ n.Valid = false
+ return nil
+ }
+ err := jsonUnmarshal(payload, n.ProtoMessageVal)
+ if err != nil {
+ return fmt.Errorf("payload cannot be converted to a proto message: err: %s", err)
+ }
+ n.Valid = true
+ return nil
+}
+
+// NullProtoEnum represents a Cloud Spanner ENUM that may be NULL.
+// To write a NULL value using NullProtoEnum set ProtoEnumVal to typed nil and set Valid to true.
+type NullProtoEnum struct {
+ ProtoEnumVal protoreflect.Enum // ProtoEnumVal contains the value when Valid is true, and nil when NULL.
+ Valid bool // Valid is true if ProtoEnumVal is not NULL.
+}
+
+// IsNull implements NullableValue.IsNull for NullProtoEnum.
+func (n NullProtoEnum) IsNull() bool {
+ return !n.Valid
+}
+
+// String implements Stringer.String for NullProtoEnum.
+func (n NullProtoEnum) String() string {
+ if !n.Valid {
+ return nullString
+ }
+ return fmt.Sprintf("%v", n.ProtoEnumVal)
+}
+
+// MarshalJSON implements json.Marshaler.MarshalJSON for NullProtoEnum.
+func (n NullProtoEnum) MarshalJSON() ([]byte, error) {
+ if n.Valid && n.ProtoEnumVal != nil {
+ return []byte(fmt.Sprintf("%v", n.ProtoEnumVal.Number())), nil
+ }
+ return jsonNullBytes, nil
+}
+
+// UnmarshalJSON implements json.Unmarshaler.UnmarshalJSON for NullProtoEnum.
+func (n *NullProtoEnum) UnmarshalJSON(payload []byte) error {
+ if payload == nil {
+ return fmt.Errorf("payload should not be nil")
+ }
+ if bytes.Equal(payload, jsonNullBytes) {
+ n.ProtoEnumVal = nil
+ n.Valid = false
+ return nil
+ }
+ if reflect.ValueOf(n.ProtoEnumVal).Kind() != reflect.Ptr {
+ return errNotAPointerField(n, n.ProtoEnumVal)
+ }
+ num, err := strconv.ParseInt(string(payload), 10, 64)
+ if err != nil {
+ return fmt.Errorf("payload cannot be converted to Enum: got %v", string(payload))
+ }
+ reflect.ValueOf(n.ProtoEnumVal).Elem().SetInt(num)
+ n.Valid = true
+ return nil
+}
+
// NullRow represents a Cloud Spanner STRUCT that may be NULL.
// See also the document for Row.
// Note that NullRow is not a valid Cloud Spanner column Type.
@@ -972,7 +1077,7 @@ func (n PGJsonB) String() string {
if !n.Valid {
return nullString
}
- b, err := jsonProvider.Marshal(n.Value)
+ b, err := json.Marshal(n.Value)
if err != nil {
return fmt.Sprintf("error: %v", err)
}
@@ -994,7 +1099,7 @@ func (n *PGJsonB) UnmarshalJSON(payload []byte) error {
return nil
}
var v interface{}
- err := jsonProvider.Unmarshal(payload, &v)
+ err := jsonUnmarshal(payload, &v)
if err != nil {
return fmt.Errorf("payload cannot be converted to a struct: got %v, err: %w", string(payload), err)
}
@@ -1007,7 +1112,7 @@ func nulljson(valid bool, v interface{}) ([]byte, error) {
if !valid {
return jsonNullBytes, nil
}
- return jsonProvider.Marshal(v)
+ return json.Marshal(v)
}
// GenericColumnValue represents the generic encoded value and type of the
@@ -1063,12 +1168,22 @@ func errNilDst(dst interface{}) error {
return spannerErrorf(codes.InvalidArgument, "cannot decode into nil type %T", dst)
}
+// errNilDstField returns error for decoding into nil interface{} of Value field in NullProtoMessage or NullProtoEnum.
+func errNilDstField(dst interface{}, field string) error {
+ return spannerErrorf(codes.InvalidArgument, "field %s in %T cannot be nil", field, dst)
+}
+
// errNilArrElemType returns error for input Cloud Spanner data type being a array but without a
// non-nil array element type.
func errNilArrElemType(t *sppb.Type) error {
return spannerErrorf(codes.FailedPrecondition, "array type %v is with nil array element type", t)
}
+// errNotValidSrc returns error if Valid field is false for NullProtoMessage and NullProtoEnum
+func errNotValidSrc(dst interface{}) error {
+ return spannerErrorf(codes.InvalidArgument, "field \"Valid\" of %T cannot be set to false when writing data to Cloud Spanner. Use typed nil in %T to write null values to Cloud Spanner", dst, dst)
+}
+
func errUnsupportedEmbeddedStructFields(fname string) error {
return spannerErrorf(codes.InvalidArgument, "Embedded field: %s. Embedded and anonymous fields are not allowed "+
"when converting Go structs to Cloud Spanner STRUCT values. To create a STRUCT value with an "+
@@ -1086,6 +1201,20 @@ func errBadEncoding(v *proto3.Value, err error) error {
return spannerErrorf(codes.FailedPrecondition, "%v wasn't correctly encoded: <%v>", v, err)
}
+// errNotAPointer returns error for decoding a non pointer type.
+func errNotAPointer(dst interface{}) error {
+ return spannerErrorf(codes.InvalidArgument, "destination %T must be a pointer", dst)
+}
+
+// errNotAPointerField returns error for decoding a non pointer type.
+func errNotAPointerField(dst interface{}, dstField interface{}) error {
+ return spannerErrorf(codes.InvalidArgument, "destination %T in %T must be a pointer", dstField, dst)
+}
+
+func errNilNotAllowed(dst interface{}, name string) error {
+ return spannerErrorf(codes.InvalidArgument, "destination %T does not support Null values. Use %s, an array with pointer type elements to read Null values", dst, name)
+}
+
func parseNullTime(v *proto3.Value, p *NullTime, code sppb.TypeCode, isNull bool) error {
if p == nil {
return errNilDst(p)
@@ -1246,7 +1375,7 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO
if p == nil {
return errNilDst(p)
}
- if code != sppb.TypeCode_BYTES {
+ if code != sppb.TypeCode_BYTES && code != sppb.TypeCode_PROTO {
return errTypeMismatch(code, acode, ptr)
}
if isNull {
@@ -1266,7 +1395,7 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO
if p == nil {
return errNilDst(p)
}
- if acode != sppb.TypeCode_BYTES {
+ if acode != sppb.TypeCode_BYTES && acode != sppb.TypeCode_PROTO {
return errTypeMismatch(code, acode, ptr)
}
if isNull {
@@ -1286,7 +1415,7 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO
if p == nil {
return errNilDst(p)
}
- if code != sppb.TypeCode_INT64 {
+ if code != sppb.TypeCode_INT64 && code != sppb.TypeCode_ENUM {
return errTypeMismatch(code, acode, ptr)
}
if isNull {
@@ -1305,7 +1434,7 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO
if p == nil {
return errNilDst(p)
}
- if code != sppb.TypeCode_INT64 {
+ if code != sppb.TypeCode_INT64 && code != sppb.TypeCode_ENUM {
return errTypeMismatch(code, acode, ptr)
}
if isNull {
@@ -1336,7 +1465,7 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO
if p == nil {
return errNilDst(p)
}
- if acode != sppb.TypeCode_INT64 {
+ if acode != sppb.TypeCode_INT64 && acode != sppb.TypeCode_ENUM {
return errTypeMismatch(code, acode, ptr)
}
if isNull {
@@ -1370,7 +1499,7 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO
if p == nil {
return errNilDst(p)
}
- if acode != sppb.TypeCode_INT64 {
+ if acode != sppb.TypeCode_INT64 && acode != sppb.TypeCode_ENUM {
return errTypeMismatch(code, acode, ptr)
}
if isNull {
@@ -1714,7 +1843,7 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO
}
x := v.GetStringValue()
var y interface{}
- err := jsonProvider.Unmarshal([]byte(x), &y)
+ err := jsonUnmarshal([]byte(x), &y)
if err != nil {
return err
}
@@ -1873,7 +2002,7 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO
}
x := v.GetStringValue()
var y interface{}
- err := jsonProvider.Unmarshal([]byte(x), &y)
+ err := jsonUnmarshal([]byte(x), &y)
if err != nil {
return err
}
@@ -2104,6 +2233,94 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO
*p = y
case *GenericColumnValue:
*p = GenericColumnValue{Type: t, Value: v}
+ case protoreflect.Enum:
+ if p == nil {
+ return errNilDst(p)
+ }
+ if reflect.ValueOf(p).Kind() != reflect.Ptr {
+ return errNotAPointer(p)
+ }
+ if code != sppb.TypeCode_ENUM && code != sppb.TypeCode_INT64 {
+ return errTypeMismatch(code, acode, ptr)
+ }
+ if isNull {
+ return errDstNotForNull(ptr)
+ }
+ y, err := getIntegerFromStringValue(v)
+ if err != nil {
+ return err
+ }
+ reflect.ValueOf(p).Elem().SetInt(y)
+ case *NullProtoEnum:
+ if p == nil {
+ return errNilDst(p)
+ }
+ if p.ProtoEnumVal == nil {
+ return errNilDstField(p, "ProtoEnumVal")
+ }
+ if reflect.ValueOf(p.ProtoEnumVal).Kind() != reflect.Ptr {
+ return errNotAPointer(p)
+ }
+ if code != sppb.TypeCode_ENUM && code != sppb.TypeCode_INT64 {
+ return errTypeMismatch(code, acode, ptr)
+ }
+ if isNull {
+ *p = NullProtoEnum{}
+ break
+ }
+ y, err := getIntegerFromStringValue(v)
+ if err != nil {
+ return err
+ }
+ reflect.ValueOf(p.ProtoEnumVal).Elem().SetInt(y)
+ p.Valid = true
+ case proto.Message:
+ if p == nil {
+ return errNilDst(p)
+ }
+ if reflect.ValueOf(p).Kind() != reflect.Ptr {
+ return errNotAPointer(p)
+ }
+ if code != sppb.TypeCode_PROTO && code != sppb.TypeCode_BYTES {
+ return errTypeMismatch(code, acode, ptr)
+ }
+ if isNull {
+ return errDstNotForNull(ptr)
+ }
+ y, err := getBytesFromStringValue(v)
+ if err != nil {
+ return err
+ }
+ err = proto.Unmarshal(y, p)
+ if err != nil {
+ return err
+ }
+ case *NullProtoMessage:
+ if p == nil {
+ return errNilDst(p)
+ }
+ if p.ProtoMessageVal == nil {
+ return errNilDstField(p, "ProtoMessageVal")
+ }
+ if reflect.ValueOf(p.ProtoMessageVal).Kind() != reflect.Ptr {
+ return errNotAPointer(p.ProtoMessageVal)
+ }
+ if code != sppb.TypeCode_PROTO && code != sppb.TypeCode_BYTES {
+ return errTypeMismatch(code, acode, ptr)
+ }
+ if isNull {
+ *p = NullProtoMessage{}
+ break
+ }
+ y, err := getBytesFromStringValue(v)
+ if err != nil {
+ return err
+ }
+ err = proto.Unmarshal(y, p.ProtoMessageVal)
+ if err != nil {
+ return err
+ }
+ p.Valid = true
default:
// Check if the pointer is a custom type that implements spanner.Decoder
// interface.
@@ -2124,6 +2341,42 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO
return decodableType.decodeValueToCustomType(v, t, acode, atypeAnnotation, ptr)
}
+ rv := reflect.ValueOf(ptr)
+ typ := rv.Type()
+ // Check if the interface{} is a pointer and is of type array of proto columns
+ if typ.Kind() == reflect.Ptr && isAnArrayOfProtoColumn(ptr) && code == sppb.TypeCode_ARRAY {
+ if isNull {
+ rv.Elem().Set(reflect.Zero(rv.Elem().Type()))
+ break
+ }
+ // Get the user-defined type of the proto array
+ etyp := typ.Elem().Elem()
+ switch acode {
+ case sppb.TypeCode_PROTO, sppb.TypeCode_BYTES:
+ if etyp.Implements(protoMsgReflectType) {
+ if etyp.Kind() == reflect.Ptr {
+ x, err := getListValue(v)
+ if err != nil {
+ return err
+ }
+ return decodeProtoMessagePtrArray(x, t.ArrayElementType, rv)
+ }
+ return errTypeMismatch(code, acode, ptr)
+ }
+ case sppb.TypeCode_ENUM, sppb.TypeCode_INT64:
+ if etyp.Implements(protoEnumReflectType) {
+ x, err := getListValue(v)
+ if err != nil {
+ return err
+ }
+ if etyp.Kind() == reflect.Ptr {
+ return decodeProtoEnumPtrArray(x, t.ArrayElementType, rv)
+ }
+ return decodeProtoEnumArray(x, t.ArrayElementType, rv, ptr)
+ }
+ }
+ }
+
// Check if the proto encoding is for an array of structs.
if !(code == sppb.TypeCode_ARRAY && acode == sppb.TypeCode_STRUCT) {
return errTypeMismatch(code, acode, ptr)
@@ -2566,7 +2819,7 @@ func (dsc decodableSpannerType) decodeValueToCustomType(v *proto3.Value, t *sppb
}
x := v.GetStringValue()
var y interface{}
- err := jsonProvider.Unmarshal([]byte(x), &y)
+ err := jsonUnmarshal([]byte(x), &y)
if err != nil {
return err
}
@@ -2581,7 +2834,7 @@ func (dsc decodableSpannerType) decodeValueToCustomType(v *proto3.Value, t *sppb
}
x := v.GetStringValue()
var y interface{}
- err := jsonProvider.Unmarshal([]byte(x), &y)
+ err := jsonUnmarshal([]byte(x), &y)
if err != nil {
return err
}
@@ -2838,6 +3091,32 @@ func errSrcVal(v *proto3.Value, want string) error {
v, v.GetKind(), want)
}
+// getIntegerFromStringValue returns the integer value of the string value encoded in proto3.Value v
+func getIntegerFromStringValue(v *proto3.Value) (int64, error) {
+ x, err := getStringValue(v)
+ if err != nil {
+ return 0, err
+ }
+ y, err := strconv.ParseInt(x, 10, 64)
+ if err != nil {
+ return 0, errBadEncoding(v, err)
+ }
+ return y, nil
+}
+
+// getBytesFromStringValue returns the bytes value of the string value encoded in proto3.Value v
+func getBytesFromStringValue(v *proto3.Value) ([]byte, error) {
+ x, err := getStringValue(v)
+ if err != nil {
+ return nil, err
+ }
+ y, err := base64.StdEncoding.DecodeString(x)
+ if err != nil {
+ return nil, errBadEncoding(v, err)
+ }
+ return y, nil
+}
+
// getStringValue returns the string value encoded in proto3.Value v whose
// kind is proto3.Value_StringValue.
func getStringValue(v *proto3.Value) (string, error) {
@@ -3272,7 +3551,7 @@ func decodeNullJSONArrayToNullJSON(pb *proto3.ListValue) (*NullJSON, error) {
}
s := fmt.Sprintf("[%s]", strings.Join(strs, ","))
var y interface{}
- err := jsonProvider.Unmarshal([]byte(s), &y)
+ err := jsonUnmarshal([]byte(s), &y)
if err != nil {
return nil, err
}
@@ -3335,6 +3614,83 @@ func decodeByteArray(pb *proto3.ListValue) ([][]byte, error) {
return a, nil
}
+// decodeProtoMessagePtrArray decodes proto3.ListValue pb into a *proto.Message slice.
+// The elements in the array implements proto.Message interface only if the element is a pointer (e.g. *ProtoMessage).
+// However, if the element is a value (e.g. ProtoMessage), then it does not implement proto.Message.
+// Therefore, decodeProtoMessagePtrArray allows decoding of proto message array if the array element is a pointer only.
+func decodeProtoMessagePtrArray(pb *proto3.ListValue, t *sppb.Type, rv reflect.Value) error {
+ if pb == nil {
+ return errNilListValue("PROTO")
+ }
+ etyp := rv.Type().Elem().Elem().Elem()
+ a := reflect.MakeSlice(rv.Type().Elem(), len(pb.Values), len(pb.Values))
+ for i, v := range pb.Values {
+ _, isNull := v.Kind.(*proto3.Value_NullValue)
+ if isNull {
+ continue
+ }
+ msg := reflect.New(etyp).Interface().(proto.Message)
+ if err := decodeValue(v, t, msg); err != nil {
+ return errDecodeArrayElement(i, v, "PROTO", err)
+ }
+ a.Index(i).Set(reflect.ValueOf(msg))
+ }
+ rv.Elem().Set(a)
+ return nil
+}
+
+// decodeProtoEnumPtrArray decodes proto3.ListValue pb into a *protoreflect.Enum slice.
+func decodeProtoEnumPtrArray(pb *proto3.ListValue, t *sppb.Type, rv reflect.Value) error {
+ if pb == nil {
+ return errNilListValue("ENUM")
+ }
+ etyp := rv.Type().Elem().Elem().Elem()
+ a := reflect.MakeSlice(rv.Type().Elem(), len(pb.Values), len(pb.Values))
+ for i, v := range pb.Values {
+ _, isNull := v.Kind.(*proto3.Value_NullValue)
+ if isNull {
+ continue
+ }
+ enum := reflect.New(etyp).Interface().(protoreflect.Enum)
+ if err := decodeValue(v, t, enum); err != nil {
+ return errDecodeArrayElement(i, v, "ENUM", err)
+ }
+ a.Index(i).Set(reflect.ValueOf(enum))
+ }
+ rv.Elem().Set(a)
+ return nil
+}
+
+// decodeProtoEnumArray decodes proto3.ListValue pb into a protoreflect.Enum slice.
+func decodeProtoEnumArray(pb *proto3.ListValue, t *sppb.Type, rv reflect.Value, ptr interface{}) error {
+ if pb == nil {
+ return errNilListValue("ENUM")
+ }
+ a := reflect.MakeSlice(rv.Type().Elem(), len(pb.Values), len(pb.Values))
+ // decodeValue method can decode only if ENUM is a pointer type.
+ // As the ENUM element in the Array is not a pointer type we cannot use decodeValue method
+ // and hence handle it separately.
+ for i, v := range pb.Values {
+ _, isNull := v.Kind.(*proto3.Value_NullValue)
+ // As the ENUM elements in the array are value type and not pointer type,
+ // we cannot support NULL values in the array
+ if isNull {
+ return errNilNotAllowed(ptr, "*[]*protoreflect.Enum")
+ }
+ x, err := getStringValue(v)
+ if err != nil {
+ return err
+ }
+ y, err := strconv.ParseInt(x, 10, 64)
+ if err != nil {
+ return errBadEncoding(v, err)
+ }
+ a.Index(i).SetInt(y)
+ }
+ rv.Elem().Set(a)
+ return nil
+}
+
// decodeNullTimeArray decodes proto3.ListValue pb into a NullTime slice.
func decodeNullTimeArray(pb *proto3.ListValue) ([]NullTime, error) {
if pb == nil {
@@ -3929,7 +4285,7 @@ func encodeValue(v interface{}) (*proto3.Value, *sppb.Type, error) {
pt = listType(pgNumericType())
case NullJSON:
if v.Valid {
- b, err := jsonProvider.Marshal(v.Value)
+ b, err := json.Marshal(v.Value)
if err != nil {
return nil, nil, err
}
@@ -3946,7 +4302,7 @@ func encodeValue(v interface{}) (*proto3.Value, *sppb.Type, error) {
pt = listType(jsonType())
case PGJsonB:
if v.Valid {
- b, err := jsonProvider.Marshal(v.Value)
+ b, err := json.Marshal(v.Value)
if err != nil {
return nil, nil, err
}
@@ -4068,6 +4424,41 @@ func encodeValue(v interface{}) (*proto3.Value, *sppb.Type, error) {
pt = proto.Clone(v.Type).(*sppb.Type)
case []GenericColumnValue:
return nil, nil, errEncoderUnsupportedType(v)
+ case protoreflect.Enum:
+ if v != nil {
+ var protoEnumfqn string
+ rv := reflect.ValueOf(v)
+ if rv.Kind() != reflect.Ptr || !rv.IsNil() {
+ pb.Kind = stringKind(strconv.FormatInt(int64(v.Number()), 10))
+ protoEnumfqn = string(v.Descriptor().FullName())
+ } else {
+ defaultType := reflect.Zero(rv.Type().Elem()).Interface().(protoreflect.Enum)
+ protoEnumfqn = string(defaultType.Descriptor().FullName())
+ }
+ pt = protoEnumType(protoEnumfqn)
+ }
+ case NullProtoEnum:
+ if v.Valid {
+ return encodeValue(v.ProtoEnumVal)
+ }
+ return nil, nil, errNotValidSrc(v)
+ case proto.Message:
+ if v != nil {
+ if v.ProtoReflect().IsValid() {
+ bytes, err := proto.Marshal(v)
+ if err != nil {
+ return nil, nil, err
+ }
+ pb.Kind = stringKind(base64.StdEncoding.EncodeToString(bytes))
+ }
+ protoMessagefqn := string(v.ProtoReflect().Descriptor().FullName())
+ pt = protoMessageType(protoMessagefqn)
+ }
+ case NullProtoMessage:
+ if v.Valid {
+ return encodeValue(v.ProtoMessageVal)
+ }
+ return nil, nil, errNotValidSrc(v)
default:
// Check if the value is a custom type that implements spanner.Encoder
// interface.
@@ -4089,7 +4480,7 @@ func encodeValue(v interface{}) (*proto3.Value, *sppb.Type, error) {
return encodeValue(converted)
}
- if !isStructOrArrayOfStructValue(v) {
+ if !isStructOrArrayOfStructValue(v) && !isAnArrayOfProtoColumn(v) {
return nil, nil, errEncoderUnsupportedType(v)
}
typ := reflect.TypeOf(v)
@@ -4102,6 +4493,9 @@ func encodeValue(v interface{}) (*proto3.Value, *sppb.Type, error) {
// Value is a slice of Go struct values/ptrs.
if typ.Kind() == reflect.Slice {
+ if isAnArrayOfProtoColumn(v) {
+ return encodeProtoArray(v)
+ }
return encodeStructArray(v)
}
}
@@ -4376,6 +4770,42 @@ func encodeStructArray(v interface{}) (*proto3.Value, *sppb.Type, error) {
return listProto(values...), listType(elemTyp), nil
}
+// Encodes a slice of proto messages or enum in v to the spanner Value and Type
+// protos.
+func encodeProtoArray(v interface{}) (*proto3.Value, *sppb.Type, error) {
+ pb := nullProto()
+ var pt *sppb.Type
+ var err error
+ sliceval := reflect.ValueOf(v)
+ etyp := reflect.TypeOf(v).Elem()
+
+ if etyp.Implements(protoMsgReflectType) {
+ if !sliceval.IsNil() {
+ pb, err = encodeProtoMessageArray(sliceval.Len(), func(i int) reflect.Value { return sliceval.Index(i) })
+ if err != nil {
+ return nil, nil, err
+ }
+ }
+ defaultInstance := reflect.Zero(etyp).Interface().(proto.Message)
+ protoMessagefqn := string(defaultInstance.ProtoReflect().Descriptor().FullName())
+ pt = listType(protoMessageType(protoMessagefqn))
+ } else if etyp.Implements(protoEnumReflectType) {
+ if !sliceval.IsNil() {
+ pb, err = encodeProtoEnumArray(sliceval.Len(), func(i int) reflect.Value { return sliceval.Index(i) })
+ if err != nil {
+ return nil, nil, err
+ }
+ }
+ if etyp.Kind() == reflect.Ptr {
+ etyp = etyp.Elem()
+ }
+ defaultInstance := reflect.Zero(etyp).Interface().(protoreflect.Enum)
+ protoEnumfqn := string(defaultInstance.Descriptor().FullName())
+ pt = listType(protoEnumType(protoEnumfqn))
+ }
+ return pb, pt, nil
+}
+
func isStructOrArrayOfStructValue(v interface{}) bool {
typ := reflect.TypeOf(v)
if typ.Kind() == reflect.Slice {
@@ -4387,6 +4817,17 @@ func isStructOrArrayOfStructValue(v interface{}) bool {
return typ.Kind() == reflect.Struct
}
+func isAnArrayOfProtoColumn(v interface{}) bool {
+ typ := reflect.TypeOf(v)
+ if typ.Kind() == reflect.Ptr {
+ typ = typ.Elem()
+ }
+ if typ.Kind() == reflect.Slice {
+ typ = typ.Elem()
+ }
+ return typ.Implements(protoMsgReflectType) || typ.Implements(protoEnumReflectType)
+}
+
func isSupportedMutationType(v interface{}) bool {
switch v.(type) {
case nil, string, *string, NullString, []string, []*string, []NullString,
@@ -4398,7 +4839,7 @@ func isSupportedMutationType(v interface{}) bool {
time.Time, *time.Time, []time.Time, []*time.Time, NullTime, []NullTime,
civil.Date, *civil.Date, []civil.Date, []*civil.Date, NullDate, []NullDate,
big.Rat, *big.Rat, []big.Rat, []*big.Rat, NullNumeric, []NullNumeric,
- GenericColumnValue:
+ GenericColumnValue, proto.Message, protoreflect.Enum, NullProtoMessage, NullProtoEnum:
return true
default:
// Check if the custom type implements spanner.Encoder interface.
@@ -4406,6 +4847,10 @@ func isSupportedMutationType(v interface{}) bool {
return true
}
+ if isAnArrayOfProtoColumn(v) {
+ return true
+ }
+
decodableType := getDecodableSpannerType(v, false)
return decodableType != spannerTypeUnknown && decodableType != spannerTypeInvalid
}
@@ -4442,6 +4887,32 @@ func encodeArray(len int, at func(int) interface{}) (*proto3.Value, error) {
return listProto(vs...), nil
}
+func encodeProtoMessageArray(len int, at func(int) reflect.Value) (*proto3.Value, error) {
+ vs := make([]*proto3.Value, len)
+ var err error
+ for i := 0; i < len; i++ {
+ v := at(i).Interface().(proto.Message)
+ vs[i], _, err = encodeValue(v)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return listProto(vs...), nil
+}
+
+func encodeProtoEnumArray(len int, at func(int) reflect.Value) (*proto3.Value, error) {
+ vs := make([]*proto3.Value, len)
+ var err error
+ for i := 0; i < len; i++ {
+ v := at(i).Interface().(protoreflect.Enum)
+ vs[i], _, err = encodeValue(v)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return listProto(vs...), nil
+}
+
func spannerTagParser(t reflect.StructTag) (name string, keep bool, other interface{}, err error) {
if s := t.Get("spanner"); s != "" {
if s == "-" {