From b0c104f738e90a90aeda4f31482918a02eb7cb2b Mon Sep 17 00:00:00 2001 From: Google APIs Date: Mon, 24 Jan 2022 15:47:02 -0800 Subject: [PATCH] feat: add database dialect PiperOrigin-RevId: 423930262 --- google/spanner/admin/database/v1/backup.proto | 5 +- google/spanner/admin/database/v1/common.proto | 15 +++++- .../database/v1/spanner_database_admin.proto | 18 +++++-- google/spanner/v1/commit_response.proto | 6 +-- google/spanner/v1/keys.proto | 2 +- google/spanner/v1/mutation.proto | 4 +- google/spanner/v1/query_plan.proto | 38 +++++++------- google/spanner/v1/result_set.proto | 3 +- google/spanner/v1/spanner.proto | 34 ++++++------ google/spanner/v1/transaction.proto | 52 +++++++------------ google/spanner/v1/type.proto | 41 ++++++++++++--- 11 files changed, 131 insertions(+), 87 deletions(-) diff --git a/google/spanner/admin/database/v1/backup.proto b/google/spanner/admin/database/v1/backup.proto index ba57c1731c..1e9ce30058 100644 --- a/google/spanner/admin/database/v1/backup.proto +++ b/google/spanner/admin/database/v1/backup.proto @@ -16,13 +16,13 @@ syntax = "proto3"; package google.spanner.admin.database.v1; +import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/longrunning/operations.proto"; import "google/protobuf/field_mask.proto"; import "google/protobuf/timestamp.proto"; import "google/spanner/admin/database/v1/common.proto"; -import "google/api/annotations.proto"; option csharp_namespace = "Google.Cloud.Spanner.Admin.Database.V1"; option go_package = "google.golang.org/genproto/googleapis/spanner/admin/database/v1;database"; @@ -117,6 +117,9 @@ message Backup { // Output only. The encryption information for the backup. EncryptionInfo encryption_info = 8 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. The database dialect information for the backup. + DatabaseDialect database_dialect = 10 [(google.api.field_behavior) = OUTPUT_ONLY]; } // The request for [CreateBackup][google.spanner.admin.database.v1.DatabaseAdmin.CreateBackup]. diff --git a/google/spanner/admin/database/v1/common.proto b/google/spanner/admin/database/v1/common.proto index 29aabff0ba..739a486458 100644 --- a/google/spanner/admin/database/v1/common.proto +++ b/google/spanner/admin/database/v1/common.proto @@ -16,11 +16,11 @@ syntax = "proto3"; package google.spanner.admin.database.v1; +import "google/api/annotations.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/protobuf/timestamp.proto"; import "google/rpc/status.proto"; -import "google/api/annotations.proto"; option csharp_namespace = "Google.Cloud.Spanner.Admin.Database.V1"; option go_package = "google.golang.org/genproto/googleapis/spanner/admin/database/v1;database"; @@ -98,3 +98,16 @@ message EncryptionInfo { } ]; } + +// Indicates the dialect type of a database. +enum DatabaseDialect { + // Default value. This value will create a database with the + // GOOGLE_STANDARD_SQL dialect. + DATABASE_DIALECT_UNSPECIFIED = 0; + + // Google standard SQL. + GOOGLE_STANDARD_SQL = 1; + + // PostgreSQL supported SQL. + POSTGRESQL = 2; +} diff --git a/google/spanner/admin/database/v1/spanner_database_admin.proto b/google/spanner/admin/database/v1/spanner_database_admin.proto index 002717505b..89d582412d 100644 --- a/google/spanner/admin/database/v1/spanner_database_admin.proto +++ b/google/spanner/admin/database/v1/spanner_database_admin.proto @@ -24,6 +24,7 @@ import "google/iam/v1/iam_policy.proto"; import "google/iam/v1/policy.proto"; import "google/longrunning/operations.proto"; import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; import "google/protobuf/timestamp.proto"; import "google/spanner/admin/database/v1/backup.proto"; import "google/spanner/admin/database/v1/common.proto"; @@ -42,10 +43,11 @@ option (google.api.resource_definition) = { // Cloud Spanner Database Admin API // -// The Cloud Spanner Database Admin API can be used to create, drop, and -// list databases. It also enables updating the schema of pre-existing -// databases. It can be also used to create, delete and list backups for a -// database and to restore from an existing backup. +// The Cloud Spanner Database Admin API can be used to: +// * create, drop, and list databases +// * update the schema of pre-existing databases +// * create, delete and list backups for a database +// * restore a database from an existing backup service DatabaseAdmin { option (google.api.default_host) = "spanner.googleapis.com"; option (google.api.oauth_scopes) = @@ -110,6 +112,8 @@ service DatabaseAdmin { // Drops (aka deletes) a Cloud Spanner database. // Completed backups for the database will be retained according to their // `expire_time`. + // Note: Cloud Spanner might continue to accept requests for a few seconds + // after the database has been deleted. rpc DropDatabase(DropDatabaseRequest) returns (google.protobuf.Empty) { option (google.api.http) = { delete: "/v1/{database=projects/*/instances/*/databases/*}" @@ -407,6 +411,9 @@ message Database { // database option set using DatabaseAdmin.CreateDatabase or // DatabaseAdmin.UpdateDatabaseDdl. If not explicitly set, this is empty. string default_leader = 9 [(google.api.field_behavior) = OUTPUT_ONLY]; + + // Output only. The dialect of the Cloud Spanner Database. + DatabaseDialect database_dialect = 10 [(google.api.field_behavior) = OUTPUT_ONLY]; } // The request for [ListDatabases][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases]. @@ -469,6 +476,9 @@ message CreateDatabaseRequest { // specified, Cloud Spanner will encrypt/decrypt all data at rest using // Google default encryption. EncryptionConfig encryption_config = 4 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The dialect of the Cloud Spanner Database. + DatabaseDialect database_dialect = 5 [(google.api.field_behavior) = OPTIONAL]; } // Metadata type for the operation returned by diff --git a/google/spanner/v1/commit_response.proto b/google/spanner/v1/commit_response.proto index 1c2df7260b..4850600f0e 100644 --- a/google/spanner/v1/commit_response.proto +++ b/google/spanner/v1/commit_response.proto @@ -16,9 +16,9 @@ syntax = "proto3"; package google.spanner.v1; +import "google/api/annotations.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; option csharp_namespace = "Google.Cloud.Spanner.V1"; option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; @@ -36,9 +36,9 @@ message CommitResponse { // `mutation_count` value can help you maximize the number of mutations // in a transaction and minimize the number of API round trips. You can // also monitor this value to prevent transactions from exceeding the system - // [limit](http://cloud.google.com/spanner/quotas#limits_for_creating_reading_updating_and_deleting_data). + // [limit](https://cloud.google.com/spanner/quotas#limits_for_creating_reading_updating_and_deleting_data). // If the number of mutations exceeds the limit, the server returns - // [INVALID_ARGUMENT](http://cloud.google.com/spanner/docs/reference/rest/v1/Code#ENUM_VALUES.INVALID_ARGUMENT). + // [INVALID_ARGUMENT](https://cloud.google.com/spanner/docs/reference/rest/v1/Code#ENUM_VALUES.INVALID_ARGUMENT). int64 mutation_count = 1; } diff --git a/google/spanner/v1/keys.proto b/google/spanner/v1/keys.proto index d8ce0d6774..ddcd181266 100644 --- a/google/spanner/v1/keys.proto +++ b/google/spanner/v1/keys.proto @@ -16,8 +16,8 @@ syntax = "proto3"; package google.spanner.v1; -import "google/protobuf/struct.proto"; import "google/api/annotations.proto"; +import "google/protobuf/struct.proto"; option csharp_namespace = "Google.Cloud.Spanner.V1"; option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; diff --git a/google/spanner/v1/mutation.proto b/google/spanner/v1/mutation.proto index 8ba51fc9ae..ccadb2f8fc 100644 --- a/google/spanner/v1/mutation.proto +++ b/google/spanner/v1/mutation.proto @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,9 +16,9 @@ syntax = "proto3"; package google.spanner.v1; +import "google/api/annotations.proto"; import "google/protobuf/struct.proto"; import "google/spanner/v1/keys.proto"; -import "google/api/annotations.proto"; option csharp_namespace = "Google.Cloud.Spanner.V1"; option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; diff --git a/google/spanner/v1/query_plan.proto b/google/spanner/v1/query_plan.proto index 35f8fe21c5..690c36ea92 100644 --- a/google/spanner/v1/query_plan.proto +++ b/google/spanner/v1/query_plan.proto @@ -16,8 +16,8 @@ syntax = "proto3"; package google.spanner.v1; -import "google/protobuf/struct.proto"; import "google/api/annotations.proto"; +import "google/protobuf/struct.proto"; option csharp_namespace = "Google.Cloud.Spanner.V1"; option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; @@ -29,6 +29,24 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // Node information for nodes appearing in a [QueryPlan.plan_nodes][google.spanner.v1.QueryPlan.plan_nodes]. message PlanNode { + // The kind of [PlanNode][google.spanner.v1.PlanNode]. Distinguishes between the two different kinds of + // nodes that can appear in a query plan. + enum Kind { + // Not specified. + KIND_UNSPECIFIED = 0; + + // Denotes a Relational operator node in the expression tree. Relational + // operators represent iterative processing of rows during query execution. + // For example, a `TableScan` operation that reads rows from a table. + RELATIONAL = 1; + + // Denotes a Scalar node in the expression tree. Scalar nodes represent + // non-iterable entities in the query plan. For example, constants or + // arithmetic operators appearing inside predicate expressions or references + // to column names. + SCALAR = 2; + } + // Metadata associated with a parent-child relationship appearing in a // [PlanNode][google.spanner.v1.PlanNode]. message ChildLink { @@ -66,24 +84,6 @@ message PlanNode { map subqueries = 2; } - // The kind of [PlanNode][google.spanner.v1.PlanNode]. Distinguishes between the two different kinds of - // nodes that can appear in a query plan. - enum Kind { - // Not specified. - KIND_UNSPECIFIED = 0; - - // Denotes a Relational operator node in the expression tree. Relational - // operators represent iterative processing of rows during query execution. - // For example, a `TableScan` operation that reads rows from a table. - RELATIONAL = 1; - - // Denotes a Scalar node in the expression tree. Scalar nodes represent - // non-iterable entities in the query plan. For example, constants or - // arithmetic operators appearing inside predicate expressions or references - // to column names. - SCALAR = 2; - } - // The `PlanNode`'s index in [node list][google.spanner.v1.QueryPlan.plan_nodes]. int32 index = 1; diff --git a/google/spanner/v1/result_set.proto b/google/spanner/v1/result_set.proto index d6bb9a2831..d6ba978de2 100644 --- a/google/spanner/v1/result_set.proto +++ b/google/spanner/v1/result_set.proto @@ -16,11 +16,12 @@ syntax = "proto3"; package google.spanner.v1; +import "google/api/annotations.proto"; import "google/protobuf/struct.proto"; +import "google/spanner/v1/commit_response.proto"; import "google/spanner/v1/query_plan.proto"; import "google/spanner/v1/transaction.proto"; import "google/spanner/v1/type.proto"; -import "google/api/annotations.proto"; option cc_enable_arenas = true; option csharp_namespace = "Google.Cloud.Spanner.V1"; diff --git a/google/spanner/v1/spanner.proto b/google/spanner/v1/spanner.proto index 176123f8d4..04cc007f55 100644 --- a/google/spanner/v1/spanner.proto +++ b/google/spanner/v1/spanner.proto @@ -16,7 +16,6 @@ syntax = "proto3"; package google.spanner.v1; -import public "google/spanner/v1/commit_response.proto"; import "google/api/annotations.proto"; import "google/api/client.proto"; import "google/api/field_behavior.proto"; @@ -25,6 +24,7 @@ import "google/protobuf/empty.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/timestamp.proto"; import "google/rpc/status.proto"; +import public "google/spanner/v1/commit_response.proto"; import "google/spanner/v1/keys.proto"; import "google/spanner/v1/mutation.proto"; import "google/spanner/v1/result_set.proto"; @@ -469,6 +469,7 @@ message RequestOptions { // Legal characters for `request_tag` values are all printable characters // (ASCII 32 - 126) and the length of a request_tag is limited to 50 // characters. Values that exceed this limit are truncated. + // Any leading underscore (_) characters will be removed from the string. string request_tag = 2; // A tag used for statistics collection about this transaction. @@ -476,17 +477,32 @@ message RequestOptions { // that belongs to a transaction. // The value of transaction_tag should be the same for all requests belonging // to the same transaction. - // If this request doesn’t belong to any transaction, transaction_tag will be + // If this request doesn't belong to any transaction, transaction_tag will be // ignored. // Legal characters for `transaction_tag` values are all printable characters // (ASCII 32 - 126) and the length of a transaction_tag is limited to 50 // characters. Values that exceed this limit are truncated. + // Any leading underscore (_) characters will be removed from the string. string transaction_tag = 3; } // The request for [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and // [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql]. message ExecuteSqlRequest { + // Mode in which the statement must be processed. + enum QueryMode { + // The default mode. Only the statement results are returned. + NORMAL = 0; + + // This mode returns only the query plan, without any results or + // execution statistics information. + PLAN = 1; + + // This mode returns both the query plan and the execution statistics along + // with the results. + PROFILE = 2; + } + // Query optimizer configuration. message QueryOptions { // An option to control the selection of optimizer version. @@ -540,20 +556,6 @@ message ExecuteSqlRequest { string optimizer_statistics_package = 2; } - // Mode in which the statement must be processed. - enum QueryMode { - // The default mode. Only the statement results are returned. - NORMAL = 0; - - // This mode returns only the query plan, without any results or - // execution statistics information. - PLAN = 1; - - // This mode returns both the query plan and the execution statistics along - // with the results. - PROFILE = 2; - } - // Required. The session in which the SQL query should be performed. string session = 1 [ (google.api.field_behavior) = REQUIRED, diff --git a/google/spanner/v1/transaction.proto b/google/spanner/v1/transaction.proto index 30ef9dc84a..debc226e32 100644 --- a/google/spanner/v1/transaction.proto +++ b/google/spanner/v1/transaction.proto @@ -16,9 +16,9 @@ syntax = "proto3"; package google.spanner.v1; +import "google/api/annotations.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; -import "google/api/annotations.proto"; option csharp_namespace = "Google.Cloud.Spanner.V1"; option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; @@ -28,8 +28,7 @@ option java_package = "com.google.spanner.v1"; option php_namespace = "Google\\Cloud\\Spanner\\V1"; option ruby_package = "Google::Cloud::Spanner::V1"; -// # Transactions -// +// Transactions: // // Each session can have at most one active transaction at a time (note that // standalone reads and queries use a transaction internally and do count @@ -37,8 +36,7 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // completed, the session can immediately be re-used for the next transaction. // It is not necessary to create a new session for each transaction. // -// # Transaction Modes -// +// Transaction Modes: // Cloud Spanner supports three transaction modes: // // 1. Locking read-write. This type of transaction is the only way @@ -70,8 +68,7 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // may, however, read/write data in different tables within that // database. // -// ## Locking Read-Write Transactions -// +// Locking Read-Write Transactions: // Locking transactions may be used to atomically read-modify-write // data anywhere in a database. This type of transaction is externally // consistent. @@ -93,8 +90,7 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // [Rollback][google.spanner.v1.Spanner.Rollback] request to abort the // transaction. // -// ## Semantics -// +// Semantics: // Cloud Spanner can commit the transaction if all read locks it acquired // are still valid at commit time, and it is able to acquire write // locks for all writes. Cloud Spanner can abort the transaction for any @@ -106,8 +102,7 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // use Cloud Spanner locks for any sort of mutual exclusion other than // between Cloud Spanner transactions themselves. // -// ## Retrying Aborted Transactions -// +// Retrying Aborted Transactions: // When a transaction aborts, the application can choose to retry the // whole transaction again. To maximize the chances of successfully // committing the retry, the client should execute the retry in the @@ -115,27 +110,25 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // priority increases with each consecutive abort, meaning that each // attempt has a slightly better chance of success than the previous. // -// Under some circumstances (e.g., many transactions attempting to +// Under some circumstances (for example, many transactions attempting to // modify the same row(s)), a transaction can abort many times in a // short period before successfully committing. Thus, it is not a good // idea to cap the number of retries a transaction can attempt; -// instead, it is better to limit the total amount of wall time spent +// instead, it is better to limit the total amount of time spent // retrying. // -// ## Idle Transactions -// +// Idle Transactions: // A transaction is considered idle if it has no outstanding reads or // SQL queries and has not started a read or SQL query within the last 10 // seconds. Idle transactions can be aborted by Cloud Spanner so that they -// don't hold on to locks indefinitely. In that case, the commit will -// fail with error `ABORTED`. +// don't hold on to locks indefinitely. If an idle transaction is aborted, the +// commit will fail with error `ABORTED`. // // If this behavior is undesirable, periodically executing a simple -// SQL query in the transaction (e.g., `SELECT 1`) prevents the +// SQL query in the transaction (for example, `SELECT 1`) prevents the // transaction from becoming idle. // -// ## Snapshot Read-Only Transactions -// +// Snapshot Read-Only Transactions: // Snapshot read-only transactions provides a simpler method than // locking read-write transactions for doing several consistent // reads. However, this type of transaction does not support writes. @@ -172,8 +165,7 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // // Each type of timestamp bound is discussed in detail below. // -// ## Strong -// +// Strong: // Strong reads are guaranteed to see the effects of all transactions // that have committed before the start of the read. Furthermore, all // rows yielded by a single read are consistent with each other -- if @@ -188,13 +180,12 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // // See [TransactionOptions.ReadOnly.strong][google.spanner.v1.TransactionOptions.ReadOnly.strong]. // -// ## Exact Staleness -// +// Exact Staleness: // These timestamp bounds execute reads at a user-specified // timestamp. Reads at a timestamp are guaranteed to see a consistent // prefix of the global transaction history: they observe -// modifications done by all transactions with a commit timestamp <= -// the read timestamp, and observe none of the modifications done by +// modifications done by all transactions with a commit timestamp less than or +// equal to the read timestamp, and observe none of the modifications done by // transactions with a larger commit timestamp. They will block until // all conflicting transactions that may be assigned commit timestamps // <= the read timestamp have finished. @@ -210,8 +201,7 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // See [TransactionOptions.ReadOnly.read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.read_timestamp] and // [TransactionOptions.ReadOnly.exact_staleness][google.spanner.v1.TransactionOptions.ReadOnly.exact_staleness]. // -// ## Bounded Staleness -// +// Bounded Staleness: // Bounded staleness modes allow Cloud Spanner to pick the read timestamp, // subject to a user-provided staleness bound. Cloud Spanner chooses the // newest timestamp within the staleness bound that allows execution @@ -240,8 +230,7 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // See [TransactionOptions.ReadOnly.max_staleness][google.spanner.v1.TransactionOptions.ReadOnly.max_staleness] and // [TransactionOptions.ReadOnly.min_read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.min_read_timestamp]. // -// ## Old Read Timestamps and Garbage Collection -// +// Old Read Timestamps and Garbage Collection: // Cloud Spanner continuously garbage collects deleted and overwritten data // in the background to reclaim storage space. This process is known // as "version GC". By default, version GC reclaims versions after they @@ -251,8 +240,7 @@ option ruby_package = "Google::Cloud::Spanner::V1"; // timestamp become too old while executing. Reads and SQL queries with // too-old read timestamps fail with the error `FAILED_PRECONDITION`. // -// ## Partitioned DML Transactions -// +// Partitioned DML Transactions: // Partitioned DML transactions are used to execute DML statements with a // different execution strategy that provides different, and often better, // scalability properties for large, table-wide operations than DML in a diff --git a/google/spanner/v1/type.proto b/google/spanner/v1/type.proto index c1f30f5123..f88e7b251d 100644 --- a/google/spanner/v1/type.proto +++ b/google/spanner/v1/type.proto @@ -16,8 +16,8 @@ syntax = "proto3"; package google.spanner.v1; -import "google/api/field_behavior.proto"; import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; option csharp_namespace = "Google.Cloud.Spanner.V1"; option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; @@ -40,6 +40,14 @@ message Type { // If [code][google.spanner.v1.Type.code] == [STRUCT][google.spanner.v1.TypeCode.STRUCT], then `struct_type` // provides type information for the struct's fields. StructType struct_type = 3; + + // The [TypeAnnotationCode][google.spanner.v1.TypeAnnotationCode] that disambiguates SQL type that Spanner will + // use to represent values of this type during query processing. This is + // necessary for some type codes because a single [TypeCode][google.spanner.v1.TypeCode] can be mapped + // to different SQL types depending on the SQL dialect. [type_annotation][google.spanner.v1.Type.type_annotation] + // typically is not needed to process the content of a value (it doesn't + // affect serialization) and clients can ignore it on the read path. + TypeAnnotationCode type_annotation = 4; } // `StructType` defines the fields of a [STRUCT][google.spanner.v1.TypeCode.STRUCT] type. @@ -129,12 +137,31 @@ enum TypeCode { //
(ExponentIndicator is `"e"` or `"E"`) NUMERIC = 10; - // Encoded as a JSON-formatted 'string' as described in RFC 7159. The - // following rules will be applied when parsing JSON input: - // - Whitespace will be stripped from the document. - // - If a JSON object has duplicate keys, only the first key will be - // preserved. + // Encoded as a JSON-formatted `string` as described in RFC 7159. The + // following rules are applied when parsing JSON input: + // + // - Whitespace characters are not preserved. + // - If a JSON object has duplicate keys, only the first key is preserved. // - Members of a JSON object are not guaranteed to have their order - // preserved. JSON array elements will have their order preserved. + // preserved. + // - JSON array elements will have their order preserved. JSON = 11; } + +// `TypeAnnotationCode` is used as a part of [Type][google.spanner.v1.Type] to +// disambiguate SQL types that should be used for a given Cloud Spanner value. +// Disambiguation is needed because the same Cloud Spanner type can be mapped to +// different SQL types depending on SQL dialect. TypeAnnotationCode doesn't +// affect the way value is serialized. +enum TypeAnnotationCode { + // Not specified. + TYPE_ANNOTATION_CODE_UNSPECIFIED = 0; + + // PostgreSQL compatible NUMERIC type. This annotation needs to be applied to + // [Type][google.spanner.v1.Type] instances having [NUMERIC][google.spanner.v1.TypeCode.NUMERIC] + // type code to specify that values of this type should be treated as + // PostgreSQL NUMERIC values. Currently this annotation is always needed for + // [NUMERIC][google.spanner.v1.TypeCode.NUMERIC] when a client interacts with PostgreSQL-enabled + // Spanner databases. + PG_NUMERIC = 2; +}