// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.spanner.v1;

import "google/api/annotations.proto";
import "google/api/auth.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "google/spanner/v1/keys.proto";
import "google/spanner/v1/mutation.proto";
import "google/spanner/v1/result_set.proto";
import "google/spanner/v1/transaction.proto";
import "google/spanner/v1/type.proto";

option csharp_namespace = "Google.Cloud.Spanner.V1";
option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner";
option java_multiple_files = true;
option java_outer_classname = "SpannerProto";
option java_package = "com.google.spanner.v1";


// Cloud Spanner API
//
// The Cloud Spanner API can be used to manage sessions and execute
// transactions on data stored in Cloud Spanner databases.
service Spanner {
  // Creates a new session. A session can be used to perform
  // transactions that read and/or modify data in a Cloud Spanner database.
  // Sessions are meant to be reused for many consecutive
  // transactions.
  //
  // Sessions can only execute one transaction at a time. To execute
  // multiple concurrent read-write/write-only transactions, create
  // multiple sessions. Note that standalone reads and queries use a
  // transaction internally, and count toward the one transaction
  // limit.
  //
  // Cloud Spanner limits the number of sessions that can exist at any given
  // time; thus, it is a good idea to delete idle and/or unneeded sessions.
  // Aside from explicit deletes, Cloud Spanner can delete sessions for which no
  // operations are sent for more than an hour. If a session is deleted,
  // requests to it return `NOT_FOUND`.
  //
  // Idle sessions can be kept alive by sending a trivial SQL query
  // periodically, e.g., `"SELECT 1"`.
  rpc CreateSession(CreateSessionRequest) returns (Session) {
    option (google.api.http) = { post: "/v1/{database=projects/*/instances/*/databases/*}/sessions" body: "" };
  }

  // Gets a session. Returns `NOT_FOUND` if the session does not exist.
  // This is mainly useful for determining whether a session is still
  // alive.
  rpc GetSession(GetSessionRequest) returns (Session) {
    option (google.api.http) = { get: "/v1/{name=projects/*/instances/*/databases/*/sessions/*}" };
  }

  // Ends a session, releasing server resources associated with it.
  rpc DeleteSession(DeleteSessionRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { delete: "/v1/{name=projects/*/instances/*/databases/*/sessions/*}" };
  }

  // Executes an SQL query, returning all rows in a single reply. This
  // method cannot be used to return a result set larger than 10 MiB;
  // if the query yields more data than that, the query fails with
  // a `FAILED_PRECONDITION` error.
  //
  // Queries inside read-write transactions might return `ABORTED`. If
  // this occurs, the application should restart the transaction from
  // the beginning. See [Transaction][google.spanner.v1.Transaction] for more details.
  //
  // Larger result sets can be fetched in streaming fashion by calling
  // [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] instead.
  rpc ExecuteSql(ExecuteSqlRequest) returns (ResultSet) {
    option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:executeSql" body: "*" };
  }

  // Like [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], except returns the result
  // set as a stream. Unlike [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], there
  // is no limit on the size of the returned result set. However, no
  // individual row in the result set can exceed 100 MiB, and no
  // column value can exceed 10 MiB.
  rpc ExecuteStreamingSql(ExecuteSqlRequest) returns (stream PartialResultSet) {
    option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:executeStreamingSql" body: "*" };
  }

  // Reads rows from the database using key lookups and scans, as a
  // simple key/value style alternative to
  // [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql].  This method cannot be used to
  // return a result set larger than 10 MiB; if the read matches more
  // data than that, the read fails with a `FAILED_PRECONDITION`
  // error.
  //
  // Reads inside read-write transactions might return `ABORTED`. If
  // this occurs, the application should restart the transaction from
  // the beginning. See [Transaction][google.spanner.v1.Transaction] for more details.
  //
  // Larger result sets can be yielded in streaming fashion by calling
  // [StreamingRead][google.spanner.v1.Spanner.StreamingRead] instead.
  rpc Read(ReadRequest) returns (ResultSet) {
    option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:read" body: "*" };
  }

  // Like [Read][google.spanner.v1.Spanner.Read], except returns the result set as a
  // stream. Unlike [Read][google.spanner.v1.Spanner.Read], there is no limit on the
  // size of the returned result set. However, no individual row in
  // the result set can exceed 100 MiB, and no column value can exceed
  // 10 MiB.
  rpc StreamingRead(ReadRequest) returns (stream PartialResultSet) {
    option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:streamingRead" body: "*" };
  }

  // Begins a new transaction. This step can often be skipped:
  // [Read][google.spanner.v1.Spanner.Read], [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and
  // [Commit][google.spanner.v1.Spanner.Commit] can begin a new transaction as a
  // side-effect.
  rpc BeginTransaction(BeginTransactionRequest) returns (Transaction) {
    option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:beginTransaction" body: "*" };
  }

  // Commits a transaction. The request includes the mutations to be
  // applied to rows in the database.
  //
  // `Commit` might return an `ABORTED` error. This can occur at any time;
  // commonly, the cause is conflicts with concurrent
  // transactions. However, it can also happen for a variety of other
  // reasons. If `Commit` returns `ABORTED`, the caller should re-attempt
  // the transaction from the beginning, re-using the same session.
  rpc Commit(CommitRequest) returns (CommitResponse) {
    option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:commit" body: "*" };
  }

  // Rolls back a transaction, releasing any locks it holds. It is a good
  // idea to call this for any transaction that includes one or more
  // [Read][google.spanner.v1.Spanner.Read] or [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] requests and
  // ultimately decides not to commit.
  //
  // `Rollback` returns `OK` if it successfully aborts the transaction, the
  // transaction was already aborted, or the transaction is not
  // found. `Rollback` never returns `ABORTED`.
  rpc Rollback(RollbackRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:rollback" body: "*" };
  }
}

// The request for [CreateSession][google.spanner.v1.Spanner.CreateSession].
message CreateSessionRequest {
  // Required. The database in which the new session is created.
  string database = 1;
}

// A session in the Cloud Spanner API.
message Session {
  // Required. The name of the session.
  string name = 1;
}

// The request for [GetSession][google.spanner.v1.Spanner.GetSession].
message GetSessionRequest {
  // Required. The name of the session to retrieve.
  string name = 1;
}

// The request for [DeleteSession][google.spanner.v1.Spanner.DeleteSession].
message DeleteSessionRequest {
  // Required. The name of the session to delete.
  string name = 1;
}

// The request for [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and
// [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql].
message ExecuteSqlRequest {
  // Mode in which the query must be processed.
  enum QueryMode {
    // The default mode where only the query result, without any information
    // about the query plan is returned.
    NORMAL = 0;

    // This mode returns only the query plan, without any result rows or
    // execution statistics information.
    PLAN = 1;

    // This mode returns both the query plan and the execution statistics along
    // with the result rows.
    PROFILE = 2;
  }

  // Required. The session in which the SQL query should be performed.
  string session = 1;

  // The transaction to use. If none is provided, the default is a
  // temporary read-only transaction with strong concurrency.
  TransactionSelector transaction = 2;

  // Required. The SQL query string.
  string sql = 3;

  // The SQL query string can contain parameter placeholders. A parameter
  // placeholder consists of `'@'` followed by the parameter
  // name. Parameter names consist of any combination of letters,
  // numbers, and underscores.
  //
  // Parameters can appear anywhere that a literal value is expected.  The same
  // parameter name can be used more than once, for example:
  //   `"WHERE id > @msg_id AND id < @msg_id + 100"`
  //
  // It is an error to execute an SQL query with unbound parameters.
  //
  // Parameter values are specified using `params`, which is a JSON
  // object whose keys are parameter names, and whose values are the
  // corresponding parameter values.
  google.protobuf.Struct params = 4;

  // It is not always possible for Cloud Spanner to infer the right SQL type
  // from a JSON value.  For example, values of type `BYTES` and values
  // of type `STRING` both appear in [params][google.spanner.v1.ExecuteSqlRequest.params] as JSON strings.
  //
  // In these cases, `param_types` can be used to specify the exact
  // SQL type for some or all of the SQL query parameters. See the
  // definition of [Type][google.spanner.v1.Type] for more information
  // about SQL types.
  map<string, Type> param_types = 5;

  // If this request is resuming a previously interrupted SQL query
  // execution, `resume_token` should be copied from the last
  // [PartialResultSet][google.spanner.v1.PartialResultSet] yielded before the interruption. Doing this
  // enables the new SQL query execution to resume where the last one left
  // off. The rest of the request parameters must exactly match the
  // request that yielded this token.
  bytes resume_token = 6;

  // Used to control the amount of debugging information returned in
  // [ResultSetStats][google.spanner.v1.ResultSetStats].
  QueryMode query_mode = 7;
}

// The request for [Read][google.spanner.v1.Spanner.Read] and
// [StreamingRead][google.spanner.v1.Spanner.StreamingRead].
message ReadRequest {
  // Required. The session in which the read should be performed.
  string session = 1;

  // The transaction to use. If none is provided, the default is a
  // temporary read-only transaction with strong concurrency.
  TransactionSelector transaction = 2;

  // Required. The name of the table in the database to be read.
  string table = 3;

  // If non-empty, the name of an index on [table][google.spanner.v1.ReadRequest.table]. This index is
  // used instead of the table primary key when interpreting [key_set][google.spanner.v1.ReadRequest.key_set]
  // and sorting result rows. See [key_set][google.spanner.v1.ReadRequest.key_set] for further information.
  string index = 4;

  // The columns of [table][google.spanner.v1.ReadRequest.table] to be returned for each row matching
  // this request.
  repeated string columns = 5;

  // Required. `key_set` identifies the rows to be yielded. `key_set` names the
  // primary keys of the rows in [table][google.spanner.v1.ReadRequest.table] to be yielded, unless [index][google.spanner.v1.ReadRequest.index]
  // is present. If [index][google.spanner.v1.ReadRequest.index] is present, then [key_set][google.spanner.v1.ReadRequest.key_set] instead names
  // index keys in [index][google.spanner.v1.ReadRequest.index].
  //
  // Rows are yielded in table primary key order (if [index][google.spanner.v1.ReadRequest.index] is empty)
  // or index key order (if [index][google.spanner.v1.ReadRequest.index] is non-empty).
  //
  // It is not an error for the `key_set` to name rows that do not
  // exist in the database. Read yields nothing for nonexistent rows.
  KeySet key_set = 6;

  // If greater than zero, only the first `limit` rows are yielded. If `limit`
  // is zero, the default is no limit.
  int64 limit = 8;

  // If this request is resuming a previously interrupted read,
  // `resume_token` should be copied from the last
  // [PartialResultSet][google.spanner.v1.PartialResultSet] yielded before the interruption. Doing this
  // enables the new read to resume where the last read left off. The
  // rest of the request parameters must exactly match the request
  // that yielded this token.
  bytes resume_token = 9;
}

// The request for [BeginTransaction][google.spanner.v1.Spanner.BeginTransaction].
message BeginTransactionRequest {
  // Required. The session in which the transaction runs.
  string session = 1;

  // Required. Options for the new transaction.
  TransactionOptions options = 2;
}

// The request for [Commit][google.spanner.v1.Spanner.Commit].
message CommitRequest {
  // Required. The session in which the transaction to be committed is running.
  string session = 1;

  // Required. The transaction in which to commit.
  oneof transaction {
    // Commit a previously-started transaction.
    bytes transaction_id = 2;

    // Execute mutations in a temporary transaction. Note that unlike
    // commit of a previously-started transaction, commit with a
    // temporary transaction is non-idempotent. That is, if the
    // `CommitRequest` is sent to Cloud Spanner more than once (for
    // instance, due to retries in the application, or in the
    // transport library), it is possible that the mutations are
    // executed more than once. If this is undesirable, use
    // [BeginTransaction][google.spanner.v1.Spanner.BeginTransaction] and
    // [Commit][google.spanner.v1.Spanner.Commit] instead.
    TransactionOptions single_use_transaction = 3;
  }

  // The mutations to be executed when this transaction commits. All
  // mutations are applied atomically, in the order they appear in
  // this list.
  repeated Mutation mutations = 4;
}

// The response for [Commit][google.spanner.v1.Spanner.Commit].
message CommitResponse {
  // The Cloud Spanner timestamp at which the transaction committed.
  google.protobuf.Timestamp commit_timestamp = 1;
}

// The request for [Rollback][google.spanner.v1.Spanner.Rollback].
message RollbackRequest {
  // Required. The session in which the transaction to roll back is running.
  string session = 1;

  // Required. The transaction to roll back.
  bytes transaction_id = 2;
}
