1*d5c09012SAndroid Build Coastguard Worker// Copyright 2022 Google LLC 2*d5c09012SAndroid Build Coastguard Worker// 3*d5c09012SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*d5c09012SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*d5c09012SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*d5c09012SAndroid Build Coastguard Worker// 7*d5c09012SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*d5c09012SAndroid Build Coastguard Worker// 9*d5c09012SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*d5c09012SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*d5c09012SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*d5c09012SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*d5c09012SAndroid Build Coastguard Worker// limitations under the License. 14*d5c09012SAndroid Build Coastguard Worker 15*d5c09012SAndroid Build Coastguard Workersyntax = "proto3"; 16*d5c09012SAndroid Build Coastguard Worker 17*d5c09012SAndroid Build Coastguard Workerpackage google.spanner.v1; 18*d5c09012SAndroid Build Coastguard Worker 19*d5c09012SAndroid Build Coastguard Workerimport "google/protobuf/struct.proto"; 20*d5c09012SAndroid Build Coastguard Workerimport "google/spanner/v1/query_plan.proto"; 21*d5c09012SAndroid Build Coastguard Workerimport "google/spanner/v1/transaction.proto"; 22*d5c09012SAndroid Build Coastguard Workerimport "google/spanner/v1/type.proto"; 23*d5c09012SAndroid Build Coastguard Worker 24*d5c09012SAndroid Build Coastguard Workeroption cc_enable_arenas = true; 25*d5c09012SAndroid Build Coastguard Workeroption csharp_namespace = "Google.Cloud.Spanner.V1"; 26*d5c09012SAndroid Build Coastguard Workeroption go_package = "cloud.google.com/go/spanner/apiv1/spannerpb;spannerpb"; 27*d5c09012SAndroid Build Coastguard Workeroption java_multiple_files = true; 28*d5c09012SAndroid Build Coastguard Workeroption java_outer_classname = "ResultSetProto"; 29*d5c09012SAndroid Build Coastguard Workeroption java_package = "com.google.spanner.v1"; 30*d5c09012SAndroid Build Coastguard Workeroption php_namespace = "Google\\Cloud\\Spanner\\V1"; 31*d5c09012SAndroid Build Coastguard Workeroption ruby_package = "Google::Cloud::Spanner::V1"; 32*d5c09012SAndroid Build Coastguard Worker 33*d5c09012SAndroid Build Coastguard Worker// Results from [Read][google.spanner.v1.Spanner.Read] or 34*d5c09012SAndroid Build Coastguard Worker// [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. 35*d5c09012SAndroid Build Coastguard Workermessage ResultSet { 36*d5c09012SAndroid Build Coastguard Worker // Metadata about the result set, such as row type information. 37*d5c09012SAndroid Build Coastguard Worker ResultSetMetadata metadata = 1; 38*d5c09012SAndroid Build Coastguard Worker 39*d5c09012SAndroid Build Coastguard Worker // Each element in `rows` is a row whose format is defined by 40*d5c09012SAndroid Build Coastguard Worker // [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element 41*d5c09012SAndroid Build Coastguard Worker // in each row matches the ith field in 42*d5c09012SAndroid Build Coastguard Worker // [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are 43*d5c09012SAndroid Build Coastguard Worker // encoded based on type as described 44*d5c09012SAndroid Build Coastguard Worker // [here][google.spanner.v1.TypeCode]. 45*d5c09012SAndroid Build Coastguard Worker repeated google.protobuf.ListValue rows = 2; 46*d5c09012SAndroid Build Coastguard Worker 47*d5c09012SAndroid Build Coastguard Worker // Query plan and execution statistics for the SQL statement that 48*d5c09012SAndroid Build Coastguard Worker // produced this result set. These can be requested by setting 49*d5c09012SAndroid Build Coastguard Worker // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. 50*d5c09012SAndroid Build Coastguard Worker // DML statements always produce stats containing the number of rows 51*d5c09012SAndroid Build Coastguard Worker // modified, unless executed using the 52*d5c09012SAndroid Build Coastguard Worker // [ExecuteSqlRequest.QueryMode.PLAN][google.spanner.v1.ExecuteSqlRequest.QueryMode.PLAN] [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. 53*d5c09012SAndroid Build Coastguard Worker // Other fields may or may not be populated, based on the 54*d5c09012SAndroid Build Coastguard Worker // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. 55*d5c09012SAndroid Build Coastguard Worker ResultSetStats stats = 3; 56*d5c09012SAndroid Build Coastguard Worker} 57*d5c09012SAndroid Build Coastguard Worker 58*d5c09012SAndroid Build Coastguard Worker// Partial results from a streaming read or SQL query. Streaming reads and 59*d5c09012SAndroid Build Coastguard Worker// SQL queries better tolerate large result sets, large rows, and large 60*d5c09012SAndroid Build Coastguard Worker// values, but are a little trickier to consume. 61*d5c09012SAndroid Build Coastguard Workermessage PartialResultSet { 62*d5c09012SAndroid Build Coastguard Worker // Metadata about the result set, such as row type information. 63*d5c09012SAndroid Build Coastguard Worker // Only present in the first response. 64*d5c09012SAndroid Build Coastguard Worker ResultSetMetadata metadata = 1; 65*d5c09012SAndroid Build Coastguard Worker 66*d5c09012SAndroid Build Coastguard Worker // A streamed result set consists of a stream of values, which might 67*d5c09012SAndroid Build Coastguard Worker // be split into many `PartialResultSet` messages to accommodate 68*d5c09012SAndroid Build Coastguard Worker // large rows and/or large values. Every N complete values defines a 69*d5c09012SAndroid Build Coastguard Worker // row, where N is equal to the number of entries in 70*d5c09012SAndroid Build Coastguard Worker // [metadata.row_type.fields][google.spanner.v1.StructType.fields]. 71*d5c09012SAndroid Build Coastguard Worker // 72*d5c09012SAndroid Build Coastguard Worker // Most values are encoded based on type as described 73*d5c09012SAndroid Build Coastguard Worker // [here][google.spanner.v1.TypeCode]. 74*d5c09012SAndroid Build Coastguard Worker // 75*d5c09012SAndroid Build Coastguard Worker // It is possible that the last value in values is "chunked", 76*d5c09012SAndroid Build Coastguard Worker // meaning that the rest of the value is sent in subsequent 77*d5c09012SAndroid Build Coastguard Worker // `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] 78*d5c09012SAndroid Build Coastguard Worker // field. Two or more chunked values can be merged to form a 79*d5c09012SAndroid Build Coastguard Worker // complete value as follows: 80*d5c09012SAndroid Build Coastguard Worker // 81*d5c09012SAndroid Build Coastguard Worker // * `bool/number/null`: cannot be chunked 82*d5c09012SAndroid Build Coastguard Worker // * `string`: concatenate the strings 83*d5c09012SAndroid Build Coastguard Worker // * `list`: concatenate the lists. If the last element in a list is a 84*d5c09012SAndroid Build Coastguard Worker // `string`, `list`, or `object`, merge it with the first element in 85*d5c09012SAndroid Build Coastguard Worker // the next list by applying these rules recursively. 86*d5c09012SAndroid Build Coastguard Worker // * `object`: concatenate the (field name, field value) pairs. If a 87*d5c09012SAndroid Build Coastguard Worker // field name is duplicated, then apply these rules recursively 88*d5c09012SAndroid Build Coastguard Worker // to merge the field values. 89*d5c09012SAndroid Build Coastguard Worker // 90*d5c09012SAndroid Build Coastguard Worker // Some examples of merging: 91*d5c09012SAndroid Build Coastguard Worker // 92*d5c09012SAndroid Build Coastguard Worker // # Strings are concatenated. 93*d5c09012SAndroid Build Coastguard Worker // "foo", "bar" => "foobar" 94*d5c09012SAndroid Build Coastguard Worker // 95*d5c09012SAndroid Build Coastguard Worker // # Lists of non-strings are concatenated. 96*d5c09012SAndroid Build Coastguard Worker // [2, 3], [4] => [2, 3, 4] 97*d5c09012SAndroid Build Coastguard Worker // 98*d5c09012SAndroid Build Coastguard Worker // # Lists are concatenated, but the last and first elements are merged 99*d5c09012SAndroid Build Coastguard Worker // # because they are strings. 100*d5c09012SAndroid Build Coastguard Worker // ["a", "b"], ["c", "d"] => ["a", "bc", "d"] 101*d5c09012SAndroid Build Coastguard Worker // 102*d5c09012SAndroid Build Coastguard Worker // # Lists are concatenated, but the last and first elements are merged 103*d5c09012SAndroid Build Coastguard Worker // # because they are lists. Recursively, the last and first elements 104*d5c09012SAndroid Build Coastguard Worker // # of the inner lists are merged because they are strings. 105*d5c09012SAndroid Build Coastguard Worker // ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] 106*d5c09012SAndroid Build Coastguard Worker // 107*d5c09012SAndroid Build Coastguard Worker // # Non-overlapping object fields are combined. 108*d5c09012SAndroid Build Coastguard Worker // {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} 109*d5c09012SAndroid Build Coastguard Worker // 110*d5c09012SAndroid Build Coastguard Worker // # Overlapping object fields are merged. 111*d5c09012SAndroid Build Coastguard Worker // {"a": "1"}, {"a": "2"} => {"a": "12"} 112*d5c09012SAndroid Build Coastguard Worker // 113*d5c09012SAndroid Build Coastguard Worker // # Examples of merging objects containing lists of strings. 114*d5c09012SAndroid Build Coastguard Worker // {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} 115*d5c09012SAndroid Build Coastguard Worker // 116*d5c09012SAndroid Build Coastguard Worker // For a more complete example, suppose a streaming SQL query is 117*d5c09012SAndroid Build Coastguard Worker // yielding a result set whose rows contain a single string 118*d5c09012SAndroid Build Coastguard Worker // field. The following `PartialResultSet`s might be yielded: 119*d5c09012SAndroid Build Coastguard Worker // 120*d5c09012SAndroid Build Coastguard Worker // { 121*d5c09012SAndroid Build Coastguard Worker // "metadata": { ... } 122*d5c09012SAndroid Build Coastguard Worker // "values": ["Hello", "W"] 123*d5c09012SAndroid Build Coastguard Worker // "chunked_value": true 124*d5c09012SAndroid Build Coastguard Worker // "resume_token": "Af65..." 125*d5c09012SAndroid Build Coastguard Worker // } 126*d5c09012SAndroid Build Coastguard Worker // { 127*d5c09012SAndroid Build Coastguard Worker // "values": ["orl"] 128*d5c09012SAndroid Build Coastguard Worker // "chunked_value": true 129*d5c09012SAndroid Build Coastguard Worker // "resume_token": "Bqp2..." 130*d5c09012SAndroid Build Coastguard Worker // } 131*d5c09012SAndroid Build Coastguard Worker // { 132*d5c09012SAndroid Build Coastguard Worker // "values": ["d"] 133*d5c09012SAndroid Build Coastguard Worker // "resume_token": "Zx1B..." 134*d5c09012SAndroid Build Coastguard Worker // } 135*d5c09012SAndroid Build Coastguard Worker // 136*d5c09012SAndroid Build Coastguard Worker // This sequence of `PartialResultSet`s encodes two rows, one 137*d5c09012SAndroid Build Coastguard Worker // containing the field value `"Hello"`, and a second containing the 138*d5c09012SAndroid Build Coastguard Worker // field value `"World" = "W" + "orl" + "d"`. 139*d5c09012SAndroid Build Coastguard Worker repeated google.protobuf.Value values = 2; 140*d5c09012SAndroid Build Coastguard Worker 141*d5c09012SAndroid Build Coastguard Worker // If true, then the final value in [values][google.spanner.v1.PartialResultSet.values] is chunked, and must 142*d5c09012SAndroid Build Coastguard Worker // be combined with more values from subsequent `PartialResultSet`s 143*d5c09012SAndroid Build Coastguard Worker // to obtain a complete field value. 144*d5c09012SAndroid Build Coastguard Worker bool chunked_value = 3; 145*d5c09012SAndroid Build Coastguard Worker 146*d5c09012SAndroid Build Coastguard Worker // Streaming calls might be interrupted for a variety of reasons, such 147*d5c09012SAndroid Build Coastguard Worker // as TCP connection loss. If this occurs, the stream of results can 148*d5c09012SAndroid Build Coastguard Worker // be resumed by re-sending the original request and including 149*d5c09012SAndroid Build Coastguard Worker // `resume_token`. Note that executing any other transaction in the 150*d5c09012SAndroid Build Coastguard Worker // same session invalidates the token. 151*d5c09012SAndroid Build Coastguard Worker bytes resume_token = 4; 152*d5c09012SAndroid Build Coastguard Worker 153*d5c09012SAndroid Build Coastguard Worker // Query plan and execution statistics for the statement that produced this 154*d5c09012SAndroid Build Coastguard Worker // streaming result set. These can be requested by setting 155*d5c09012SAndroid Build Coastguard Worker // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent 156*d5c09012SAndroid Build Coastguard Worker // only once with the last response in the stream. 157*d5c09012SAndroid Build Coastguard Worker // This field will also be present in the last response for DML 158*d5c09012SAndroid Build Coastguard Worker // statements. 159*d5c09012SAndroid Build Coastguard Worker ResultSetStats stats = 5; 160*d5c09012SAndroid Build Coastguard Worker} 161*d5c09012SAndroid Build Coastguard Worker 162*d5c09012SAndroid Build Coastguard Worker// Metadata about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet]. 163*d5c09012SAndroid Build Coastguard Workermessage ResultSetMetadata { 164*d5c09012SAndroid Build Coastguard Worker // Indicates the field names and types for the rows in the result 165*d5c09012SAndroid Build Coastguard Worker // set. For example, a SQL query like `"SELECT UserId, UserName FROM 166*d5c09012SAndroid Build Coastguard Worker // Users"` could return a `row_type` value like: 167*d5c09012SAndroid Build Coastguard Worker // 168*d5c09012SAndroid Build Coastguard Worker // "fields": [ 169*d5c09012SAndroid Build Coastguard Worker // { "name": "UserId", "type": { "code": "INT64" } }, 170*d5c09012SAndroid Build Coastguard Worker // { "name": "UserName", "type": { "code": "STRING" } }, 171*d5c09012SAndroid Build Coastguard Worker // ] 172*d5c09012SAndroid Build Coastguard Worker StructType row_type = 1; 173*d5c09012SAndroid Build Coastguard Worker 174*d5c09012SAndroid Build Coastguard Worker // If the read or SQL query began a transaction as a side-effect, the 175*d5c09012SAndroid Build Coastguard Worker // information about the new transaction is yielded here. 176*d5c09012SAndroid Build Coastguard Worker Transaction transaction = 2; 177*d5c09012SAndroid Build Coastguard Worker 178*d5c09012SAndroid Build Coastguard Worker // A SQL query can be parameterized. In PLAN mode, these parameters can be 179*d5c09012SAndroid Build Coastguard Worker // undeclared. This indicates the field names and types for those undeclared 180*d5c09012SAndroid Build Coastguard Worker // parameters in the SQL query. For example, a SQL query like `"SELECT * FROM 181*d5c09012SAndroid Build Coastguard Worker // Users where UserId = @userId and UserName = @userName "` could return a 182*d5c09012SAndroid Build Coastguard Worker // `undeclared_parameters` value like: 183*d5c09012SAndroid Build Coastguard Worker // 184*d5c09012SAndroid Build Coastguard Worker // "fields": [ 185*d5c09012SAndroid Build Coastguard Worker // { "name": "UserId", "type": { "code": "INT64" } }, 186*d5c09012SAndroid Build Coastguard Worker // { "name": "UserName", "type": { "code": "STRING" } }, 187*d5c09012SAndroid Build Coastguard Worker // ] 188*d5c09012SAndroid Build Coastguard Worker StructType undeclared_parameters = 3; 189*d5c09012SAndroid Build Coastguard Worker} 190*d5c09012SAndroid Build Coastguard Worker 191*d5c09012SAndroid Build Coastguard Worker// Additional statistics about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet]. 192*d5c09012SAndroid Build Coastguard Workermessage ResultSetStats { 193*d5c09012SAndroid Build Coastguard Worker // [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result. 194*d5c09012SAndroid Build Coastguard Worker QueryPlan query_plan = 1; 195*d5c09012SAndroid Build Coastguard Worker 196*d5c09012SAndroid Build Coastguard Worker // Aggregated statistics from the execution of the query. Only present when 197*d5c09012SAndroid Build Coastguard Worker // the query is profiled. For example, a query could return the statistics as 198*d5c09012SAndroid Build Coastguard Worker // follows: 199*d5c09012SAndroid Build Coastguard Worker // 200*d5c09012SAndroid Build Coastguard Worker // { 201*d5c09012SAndroid Build Coastguard Worker // "rows_returned": "3", 202*d5c09012SAndroid Build Coastguard Worker // "elapsed_time": "1.22 secs", 203*d5c09012SAndroid Build Coastguard Worker // "cpu_time": "1.19 secs" 204*d5c09012SAndroid Build Coastguard Worker // } 205*d5c09012SAndroid Build Coastguard Worker google.protobuf.Struct query_stats = 2; 206*d5c09012SAndroid Build Coastguard Worker 207*d5c09012SAndroid Build Coastguard Worker // The number of rows modified by the DML statement. 208*d5c09012SAndroid Build Coastguard Worker oneof row_count { 209*d5c09012SAndroid Build Coastguard Worker // Standard DML returns an exact count of rows that were modified. 210*d5c09012SAndroid Build Coastguard Worker int64 row_count_exact = 3; 211*d5c09012SAndroid Build Coastguard Worker 212*d5c09012SAndroid Build Coastguard Worker // Partitioned DML does not offer exactly-once semantics, so it 213*d5c09012SAndroid Build Coastguard Worker // returns a lower bound of the rows modified. 214*d5c09012SAndroid Build Coastguard Worker int64 row_count_lower_bound = 4; 215*d5c09012SAndroid Build Coastguard Worker } 216*d5c09012SAndroid Build Coastguard Worker} 217