syntax = "proto2";

import "cockroach/proto/config.proto";
import "cockroach/proto/data.proto";
import "cockroach/proto/errors.proto";
package cockroach.proto;

option go_package = "proto";

// ReadConsistencyType specifies what type of consistency is observed
//  during read operations.
enum ReadConsistencyType {
  // CONSISTENT reads are guaranteed to read committed data; the
  //  mechanism relies on clocks to determine lease expirations.
  CONSISTENT = 0;
  // CONSENSUS requires that reads must achieve consensus. This is a
  //  stronger guarantee of consistency than CONSISTENT.
  //  TODO(spencer): current unimplemented.
  CONSENSUS = 1;
  // INCONSISTENT reads return the latest available, committed values.
  //  They are more efficient, but may read stale values as pending
  //  intents are ignored.
  INCONSISTENT = 2;
}

// ClientCmdID provides a unique ID for client commands. Clients which
//  provide ClientCmdID gain operation idempotence. In other words,
//  clients can submit the same command multiple times and always
//  receive the same response. This is common on retries over flaky
//  networks. However, the system imposes a limit on how long
//  idempotence is provided. Retries over an hour old are not
//  guaranteed idempotence and may be executed more than once with
//  potentially different results.
//  ClientCmdID contains the client's timestamp and a client-generated
//  random number. The client Timestamp is specified in unix
//  nanoseconds and is used for some uniqueness but also to provide a
//  rough ordering of requests, useful for data locality on the
//  server. The Random is specified for additional uniqueness.
//  NOTE: An accurate time signal IS NOT required for correctness.
message ClientCmdID {
  // Nanoseconds since Unix epoch.
  optional int64 wall_time = 1;
  optional int64 random = 2;
}

// RequestHeader is supplied with every storage node request.
message RequestHeader {
  // Timestamp specifies time at which read or writes should be
  //  performed. If the timestamp is set to zero value, its value
  //  is initialized to the wall time of the receiving node.
  optional .cockroach.proto.Timestamp timestamp = 1;
  // CmdID is optionally specified for request idempotence
  //  (i.e. replay protection).
  optional .cockroach.proto.ClientCmdID cmd_id = 2;
  // The key for request. If the request operates on a range, this
  //  represents the starting key for the range.
  optional bytes key = 3;
  // End key is empty if request spans only a single key.
  optional bytes end_key = 4;
  // User is the originating user. Used to lookup priority when
  //  scheduling queued operations at target node.
  optional string user = 5;
  // Replica specifies the destination for the request. This is a specific
  //  instance of the available replicas belonging to RangeID.
  optional .cockroach.proto.Replica replica = 6;
  // RaftID specifies the ID of the Raft consensus group which the key
  //  range belongs to. This is used by the receiving node to route the
  //  request to the correct range.
  optional int64 raft_id = 7;
  // UserPriority specifies priority multiple for non-transactional
  //  commands. This value should be a positive integer [1, 2^31-1).
  //  It's properly viewed as a multiple for how likely this
  //  transaction will be to prevail if a write conflict occurs.
  //  Commands with UserPriority=100 will be 100x less likely to be
  //  aborted as conflicting transactions or non-transactional commands
  //  with UserPriority=1. This value is ignored if Txn is
  //  specified. If neither this value nor Txn is specified, the value
  //  defaults to 1.
  optional int32 user_priority = 8 [default = 1];
  // Txn is set non-nil if a transaction is underway. To start a txn,
  //  the first request should set this field to non-nil with name and
  //  isolation level set as desired. The response will contain the
  //  fully-initialized transaction with txn ID, priority, initial
  //  timestamp, and maximum timestamp.
  optional .cockroach.proto.Transaction txn = 9;
  // ReadConsistency specifies the consistency for read
  //  operations. The default is CONSISTENT. This value is ignored for
  //  write operations.
  optional .cockroach.proto.ReadConsistencyType read_consistency = 10;
}

// ResponseHeader is returned with every storage node response.
message ResponseHeader {
  // Error is non-nil if an error occurred.
  optional .cockroach.proto.Error error = 1;
  // Timestamp specifies time at which read or write actually was
  //  performed. In the case of both reads and writes, if the timestamp
  //  supplied to the request was 0, the wall time of the node
  //  servicing the request will be set here. Additionally, in the case
  //  of writes, this value may be increased from the timestamp passed
  //  with the RequestHeader if the key being written was either read
  //  or written more recently.
  optional .cockroach.proto.Timestamp timestamp = 2;
  // Transaction is non-nil if the request specified a non-nil
  //  transaction. The transaction timestamp and/or priority may have
  //  been updated, depending on the outcome of the request.
  optional .cockroach.proto.Transaction txn = 3;
}

// A ContainsRequest is arguments to the Contains() method.
message ContainsRequest {
  optional .cockroach.proto.RequestHeader header = 1;
}

// A ContainsResponse is the return value of the Contains() method.
message ContainsResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
  optional bool exists = 2;
}

// A GetRequest is arguments to the Get() method.
message GetRequest {
  optional .cockroach.proto.RequestHeader header = 1;
}

// A GetResponse is the return value from the Get() method.
//  If the key doesn't exist, returns nil for Value.Bytes.
message GetResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
  optional .cockroach.proto.Value value = 2;
}

// A PutRequest is arguments to the Put() method. Note that to write
//  an empty value, the value parameter is still specified, but both
//  Bytes and Integer are set to nil.
message PutRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  optional .cockroach.proto.Value value = 2;
}

// A PutResponse is the return value from the Put() method.
message PutResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

// A ConditionalPutRequest is arguments to the ConditionalPut() method.
//  - Returns true and sets value if ExpValue equals existing value.
//  - If key doesn't exist and ExpValue is nil, sets value.
//  - If key exists, but value is empty and ExpValue is not nil but empty, sets value.
//  - Otherwise, returns error and the actual value of the key in the response.
message ConditionalPutRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  // The value to put.
  optional .cockroach.proto.Value value = 2;
  // ExpValue.Bytes empty to test for non-existence. Specify as nil
  //  to indicate there should be no existing entry. This is different
  //  from the expectation that the value exists but is empty.
  optional .cockroach.proto.Value exp_value = 3;
}

// A ConditionalPutResponse is the return value from the
//  ConditionalPut() method.
message ConditionalPutResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

// An IncrementRequest is arguments to the Increment() method. It
//  increments the value for key, and returns the new value. If no
//  value exists for a key, incrementing by 0 is not a noop, but will
//  create a zero value. IncrementRequest cannot be called on a key set
//  by Put() or ConditionalPut(). Similarly, Put() and ConditionalPut()
//  cannot be invoked on an incremented key.
message IncrementRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  optional int64 increment = 2;
}

// An IncrementResponse is the return value from the Increment
//  method. The new value after increment is specified in NewValue. If
//  the value could not be decoded as specified, Error will be set.
message IncrementResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
  optional int64 new_value = 2;
}

// A DeleteRequest is arguments to the Delete() method.
message DeleteRequest {
  optional .cockroach.proto.RequestHeader header = 1;
}

// A DeleteResponse is the return value from the Delete() method.
message DeleteResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

// A DeleteRangeRequest is arguments to the DeleteRange method. It
//  specifies the range of keys to delete.
message DeleteRangeRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  // If 0, *all* entries between Key (inclusive) and EndKey
  //  (exclusive) are deleted. Must be >= 0
  optional int64 max_entries_to_delete = 2;
}

// A DeleteRangeResponse is the return value from the DeleteRange()
//  method.
message DeleteRangeResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
  // Number of entries removed.
  optional int64 num_deleted = 2;
}

// A ScanRequest is arguments to the Scan() method. It specifies the
//  start and end keys for the scan and the maximum number of results.
message ScanRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  // Must be > 0.
  optional int64 max_results = 2;
}

// A ScanResponse is the return value from the Scan() method.
message ScanResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
  // Empty if no rows were scanned.
  repeated .cockroach.proto.KeyValue rows = 2;
}

// An EndTransactionRequest is arguments to the EndTransaction() method.
//  It specifies whether to commit or roll back an extant transaction.
message EndTransactionRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  // False to abort and rollback.
  optional bool commit = 2;
  // Optional commit triggers. Note that commit triggers are for
  //  internal use only and will be ignored if requested through the
  //  public-facing KV API.
  optional .cockroach.proto.InternalCommitTrigger internal_commit_trigger = 3;
}

// An EndTransactionResponse is the return value from the
//  EndTransaction() method. The final transaction record is returned
//  as part of the response header. In particular, transaction status
//  and timestamp will be updated to reflect final committed
//  values. Clients may propagate the transaction timestamp as the
//  final txn commit timestamp in order to preserve causal ordering
//  between subsequent transactions. CommitWait specifies the commit
//  wait, which is the remaining time the client MUST wait before
//  signalling completion of the transaction to another distributed
//  node to maintain consistency.
message EndTransactionResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
  // Remaining time (ns).
  optional int64 commit_wait = 2;
  // List of intents resolved by EndTransaction call.
  repeated bytes resolved = 3;
}

// A RequestUnion contains exactly one of the optional requests.
//  Values added here must be added to InternalRequestUnion as well.
message RequestUnion {
   oneof value {
    .cockroach.proto.ContainsRequest contains = 1;
    .cockroach.proto.GetRequest get = 2;
    .cockroach.proto.PutRequest put = 3;
    .cockroach.proto.ConditionalPutRequest conditional_put = 4;
    .cockroach.proto.IncrementRequest increment = 5;
    .cockroach.proto.DeleteRequest delete = 6;
    .cockroach.proto.DeleteRangeRequest delete_range = 7;
    .cockroach.proto.ScanRequest scan = 8;
    .cockroach.proto.EndTransactionRequest end_transaction = 9;
  }
}

// A ResponseUnion contains exactly one of the optional responses.
//  Values added here must be added to InternalResponseUnion as well.
message ResponseUnion {
   oneof value {
    .cockroach.proto.ContainsResponse contains = 1;
    .cockroach.proto.GetResponse get = 2;
    .cockroach.proto.PutResponse put = 3;
    .cockroach.proto.ConditionalPutResponse conditional_put = 4;
    .cockroach.proto.IncrementResponse increment = 5;
    .cockroach.proto.DeleteResponse delete = 6;
    .cockroach.proto.DeleteRangeResponse delete_range = 7;
    .cockroach.proto.ScanResponse scan = 8;
    .cockroach.proto.EndTransactionResponse end_transaction = 9;
  }
}

// A BatchRequest contains one or more requests to be executed in
//  parallel, or if applicable (based on write-only commands and
//  range-locality), as a single update.
//  The RequestHeader should contain the Key of the first request
//  in the batch.
message BatchRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  repeated .cockroach.proto.RequestUnion requests = 2;
}

// A BatchResponse contains one or more responses, one per request
//  corresponding to the requests in the matching BatchRequest. The
//  error in the response header is set to the first error from the
//  slice of responses, if applicable.
message BatchResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
  repeated .cockroach.proto.ResponseUnion responses = 2;
}

// An AdminSplitRequest is arguments to the AdminSplit() method. The
//  existing range which contains RequestHeader.Key is split by
//  split_key. If split_key is not specified, then this method will
//  determine a split key that is roughly halfway through the
//  range. The existing range is resized to cover only its start key to
//  the split key. The new range created by the split starts at the
//  split key and extends to the original range's end key. If split_key
//  is known, header.key should also be set to split_key.
//  New range IDs for each of the split range's replica and a new Raft
//  ID are generated by the operation. Split requests are done in the
//  context of a distributed transaction which updates range addressing
//  records, range metadata and finally, provides a commit trigger to
//  update bookkeeping and instantiate the new range on commit.
//  The new range contains range replicas located on the same stores;
//  no range data is moved during this operation. The split can be
//  thought of as a mostly logical operation, though some other
//  metadata (e.g. response cache and range stats must be copied or
//  recomputed).
message AdminSplitRequest {
  optional .cockroach.proto.RequestHeader header = 1;
  optional bytes split_key = 2;
}

// An AdminSplitResponse is the return value from the AdminSplit()
//  method.
message AdminSplitResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

// An AdminMergeRequest is arguments to the AdminMerge() method. A
//  merge is performed by calling AdminMerge on the left-hand range of
//  two consecutive ranges (i.e. the range which contains keys which
//  sort first). This range will be the subsuming range and the right
//  hand range will be subsumed. After the merge operation, the
//  subsumed_range will no longer exist and the subsuming range will
//  now encompass all keys from its original start key to the end key
//  of the subsumed range. If AdminMerge is called on the final range
//  in the key space, it is a noop.
message AdminMergeRequest {
  optional .cockroach.proto.RequestHeader header = 1;
}

// An AdminMergeResponse is the return value from the AdminMerge()
//  method.
message AdminMergeResponse {
  optional .cockroach.proto.ResponseHeader header = 1;
}

