Skip to content

Commit f681f79

Browse files
Google APIscopybara-github
authored andcommitted
feat: publish the Cloud Bigtable ExecuteQuery API
The ExecuteQuery API will allow users to query Bigtable using SQL PiperOrigin-RevId: 650660213
1 parent dbc1a3c commit f681f79

File tree

4 files changed

+513
-1
lines changed

4 files changed

+513
-1
lines changed

google/bigtable/v2/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ proto_library(
4646
"feature_flags.proto",
4747
"request_stats.proto",
4848
"response_params.proto",
49+
"types.proto",
4950
],
5051
deps = [
5152
"//google/api:annotations_proto",
@@ -54,6 +55,7 @@ proto_library(
5455
"//google/api:resource_proto",
5556
"//google/api:routing_proto",
5657
"//google/rpc:status_proto",
58+
"//google/type:date_proto",
5759
"@com_google_protobuf//:duration_proto",
5860
"@com_google_protobuf//:timestamp_proto",
5961
"@com_google_protobuf//:wrappers_proto",
@@ -124,6 +126,7 @@ go_proto_library(
124126
deps = [
125127
"//google/api:annotations_go_proto",
126128
"//google/rpc:status_go_proto",
129+
"//google/type:date_go_proto",
127130
],
128131
)
129132

google/bigtable/v2/bigtable.proto

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,23 @@ service Bigtable {
274274
option (google.api.method_signature) = "table_name";
275275
option (google.api.method_signature) = "table_name,app_profile_id";
276276
}
277+
278+
// Executes a BTQL query against a particular Cloud Bigtable instance.
279+
rpc ExecuteQuery(ExecuteQueryRequest) returns (stream ExecuteQueryResponse) {
280+
option (google.api.http) = {
281+
post: "/v2/{instance_name=projects/*/instances/*}:executeQuery"
282+
body: "*"
283+
};
284+
option (google.api.routing) = {
285+
routing_parameters {
286+
field: "instance_name"
287+
path_template: "{name=projects/*/instances/*}"
288+
}
289+
routing_parameters { field: "app_profile_id" }
290+
};
291+
option (google.api.method_signature) = "instance_name,query";
292+
option (google.api.method_signature) = "instance_name,query,app_profile_id";
293+
}
277294
}
278295

279296
// Request message for Bigtable.ReadRows.
@@ -1006,3 +1023,80 @@ message ReadChangeStreamResponse {
10061023
CloseStream close_stream = 3;
10071024
}
10081025
}
1026+
1027+
// Request message for Bigtable.ExecuteQuery
1028+
message ExecuteQueryRequest {
1029+
// Required. The unique name of the instance against which the query should be
1030+
// executed.
1031+
// Values are of the form `projects/<project>/instances/<instance>`
1032+
string instance_name = 1 [
1033+
(google.api.field_behavior) = REQUIRED,
1034+
(google.api.resource_reference) = {
1035+
type: "bigtableadmin.googleapis.com/Instance"
1036+
}
1037+
];
1038+
1039+
// Optional. This value specifies routing for replication. If not specified,
1040+
// the `default` application profile will be used.
1041+
string app_profile_id = 2 [(google.api.field_behavior) = OPTIONAL];
1042+
1043+
// Required. The query string.
1044+
string query = 3 [(google.api.field_behavior) = REQUIRED];
1045+
1046+
// Required. Requested data format for the response.
1047+
oneof data_format {
1048+
// Protocol buffer format as described by ProtoSchema and ProtoRows
1049+
// messages.
1050+
ProtoFormat proto_format = 4;
1051+
}
1052+
1053+
// Optional. If this request is resuming a previously interrupted query
1054+
// execution, `resume_token` should be copied from the last
1055+
// PartialResultSet yielded before the interruption. Doing this
1056+
// enables the query execution to resume where the last one left
1057+
// off.
1058+
// The rest of the request parameters must exactly match the
1059+
// request that yielded this token. Otherwise the request will fail.
1060+
bytes resume_token = 8 [(google.api.field_behavior) = OPTIONAL];
1061+
1062+
// Required. params contains string type keys and Bigtable type values that
1063+
// bind to placeholders in the query string. In query string, a parameter
1064+
// placeholder consists of the
1065+
// `@` character followed by the parameter name (for example, `@firstName`) in
1066+
// the query string.
1067+
//
1068+
// For example, if
1069+
// `params["firstName"] = bytes_value: "foo" type {bytes_type {}}`
1070+
// then `@firstName` will be replaced with googlesql bytes value "foo" in the
1071+
// query string during query evaluation.
1072+
//
1073+
// In case of Value.kind is not set, it will be set to corresponding null
1074+
// value in googlesql.
1075+
// `params["firstName"] = type {string_type {}}`
1076+
// then `@firstName` will be replaced with googlesql null string.
1077+
//
1078+
// Value.type should always be set and no inference of type will be made from
1079+
// Value.kind. If Value.type is not set, we will return INVALID_ARGUMENT
1080+
// error.
1081+
map<string, Value> params = 7 [(google.api.field_behavior) = REQUIRED];
1082+
}
1083+
1084+
// Response message for Bigtable.ExecuteQuery
1085+
message ExecuteQueryResponse {
1086+
// The first response streamed from the server is of type `ResultSetMetadata`
1087+
// and includes information about the columns and types of the result set.
1088+
// From there on, we stream `PartialResultSet` messages with no additional
1089+
// information. `PartialResultSet` will contain `resume_token` to restart the
1090+
// response if query interrupts. In case of resumption with `resume_token`,
1091+
// the server will not resend the ResultSetMetadata.
1092+
oneof response {
1093+
// Structure of rows in this response stream. The first (and only the first)
1094+
// response streamed from the server will be of this type.
1095+
ResultSetMetadata metadata = 1;
1096+
1097+
// A partial result set with row data potentially including additional
1098+
// instructions on how recent past and future partial responses should be
1099+
// interpreted.
1100+
PartialResultSet results = 2;
1101+
}
1102+
}

google/bigtable/v2/data.proto

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ syntax = "proto3";
1717
package google.bigtable.v2;
1818

1919
import "google/api/field_behavior.proto";
20+
import "google/bigtable/v2/types.proto";
21+
import "google/protobuf/timestamp.proto";
22+
import "google/type/date.proto";
2023

2124
option csharp_namespace = "Google.Cloud.Bigtable.V2";
2225
option go_package = "google.golang.org/genproto/googleapis/bigtable/v2;bigtable";
@@ -92,6 +95,21 @@ message Cell {
9295
// value (which may be of a more complex type). See the documentation of the
9396
// `Type` message for more details.
9497
message Value {
98+
// The verified `Type` of this `Value`, if it cannot be inferred.
99+
//
100+
// Read results will never specify the encoding for `type` since the value
101+
// will already have been decoded by the server. Furthermore, the `type` will
102+
// be omitted entirely if it can be inferred from a previous response. The
103+
// exact semantics for inferring `type` will vary, and are therefore
104+
// documented separately for each read method.
105+
//
106+
// When using composite types (Struct, Array, Map) only the outermost `Value`
107+
// will specify the `type`. This top-level `type` will define the types for
108+
// any nested `Struct' fields, `Array` elements, or `Map` key/value pairs.
109+
// If a nested `Value` provides a `type` on write, the request will be
110+
// rejected with INVALID_ARGUMENT.
111+
Type type = 7;
112+
95113
// Options for transporting values within the protobuf type system. A given
96114
// `kind` may support more than one `type` and vice versa. On write, this is
97115
// roughly analogous to a GoogleSQL literal.
@@ -107,12 +125,42 @@ message Value {
107125
// The `type` field must be omitted.
108126
int64 raw_timestamp_micros = 9;
109127

128+
// Represents a typed value transported as a byte sequence.
129+
bytes bytes_value = 2;
130+
131+
// Represents a typed value transported as a string.
132+
string string_value = 3;
133+
110134
// Represents a typed value transported as an integer.
111-
// Default type for writes: `Int64`
112135
int64 int_value = 6;
136+
137+
// Represents a typed value transported as a boolean.
138+
bool bool_value = 10;
139+
140+
// Represents a typed value transported as a floating point number.
141+
double float_value = 11;
142+
143+
// Represents a typed value transported as a timestamp.
144+
google.protobuf.Timestamp timestamp_value = 12;
145+
146+
// Represents a typed value transported as a date.
147+
google.type.Date date_value = 13;
148+
149+
// Represents a typed value transported as a sequence of values.
150+
// To differentiate between `Struct`, `Array`, and `Map`, the outermost
151+
// `Value` must provide an explicit `type` on write. This `type` will
152+
// apply recursively to the nested `Struct` fields, `Array` elements,
153+
// or `Map` key/value pairs, which *must not* supply their own `type`.
154+
ArrayValue array_value = 4;
113155
}
114156
}
115157

158+
// `ArrayValue` is an ordered list of `Value`.
159+
message ArrayValue {
160+
// The ordered elements in the array.
161+
repeated Value values = 1;
162+
}
163+
116164
// Specifies a contiguous range of rows.
117165
message RowRange {
118166
// The row key at which to start the range.
@@ -609,3 +657,84 @@ message StreamContinuationToken {
609657
// An encoded position in the stream to restart reading from.
610658
string token = 2;
611659
}
660+
661+
// Protocol buffers format descriptor, as described by Messages ProtoSchema and
662+
// ProtoRows
663+
message ProtoFormat {}
664+
665+
// Describes a column in a Bigtable Query Language result set.
666+
message ColumnMetadata {
667+
// The name of the column.
668+
string name = 1;
669+
670+
// The type of the column.
671+
Type type = 2;
672+
}
673+
674+
// ResultSet schema in proto format
675+
message ProtoSchema {
676+
// The columns in the result set.
677+
repeated ColumnMetadata columns = 1;
678+
}
679+
680+
// Describes the structure of a Bigtable result set.
681+
message ResultSetMetadata {
682+
// The schema of the ResultSet, contains ordered list of column names
683+
// with types
684+
oneof schema {
685+
// Schema in proto format
686+
ProtoSchema proto_schema = 1;
687+
}
688+
}
689+
690+
// Batch of serialized ProtoRows.
691+
message ProtoRowsBatch {
692+
// Merge partial results by concatenating these bytes, then parsing the
693+
// overall value as a `ProtoRows` message.
694+
bytes batch_data = 1;
695+
}
696+
697+
// A partial result set from the streaming query API.
698+
// CBT client will buffer partial_rows from result_sets until it gets a
699+
// resumption_token.
700+
message PartialResultSet {
701+
// Partial Rows in one of the supported formats. It may require many
702+
// PartialResultSets to stream a batch of rows that can decoded on the client.
703+
// The client should buffer partial_rows until it gets a `resume_token`,
704+
// at which point the batch is complete and can be decoded and yielded to the
705+
// user. Each sub-message documents the appropriate way to combine results.
706+
oneof partial_rows {
707+
// Partial rows in serialized ProtoRows format.
708+
ProtoRowsBatch proto_rows_batch = 3;
709+
}
710+
711+
// An opaque token sent by the server to allow query resumption and signal
712+
// the client to accumulate `partial_rows` since the last non-empty
713+
// `resume_token`. On resumption, the resumed query will return the remaining
714+
// rows for this query.
715+
//
716+
// If there is a batch in progress, a non-empty `resume_token`
717+
// means that that the batch of `partial_rows` will be complete after merging
718+
// the `partial_rows` from this response. The client must only yield
719+
// completed batches to the application, and must ensure that any future
720+
// retries send the latest token to avoid returning duplicate data.
721+
//
722+
// The server may set 'resume_token' without a 'partial_rows'. If there is a
723+
// batch in progress the client should yield it.
724+
//
725+
// The server will also send a sentinel `resume_token` when last batch of
726+
// `partial_rows` is sent. If the client retries the ExecuteQueryRequest with
727+
// the sentinel `resume_token`, the server will emit it again without any
728+
// `partial_rows`, then return OK.
729+
bytes resume_token = 5;
730+
731+
// Estimated size of a new batch. The server will always set this when
732+
// returning the first `partial_rows` of a batch, and will not set it at any
733+
// other time.
734+
//
735+
// The client can use this estimate to allocate an initial buffer for the
736+
// batched results. This helps minimize the number of allocations required,
737+
// though the buffer size may still need to be increased if the estimate is
738+
// too low.
739+
int32 estimated_batch_size = 4;
740+
}

0 commit comments

Comments
 (0)