/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you 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";

option java_package = "org.apache.calcite.avatica.proto";

import "common.proto";

// Request for Meta#getCatalogs()
message CatalogsRequest {
  string connection_id = 1;
}

// Request for Meta#getDatabaseProperties()
message DatabasePropertyRequest {
  string connection_id = 1;
}

// Request for Meta#getSchemas(String, org.apache.calcite.avatica.Meta.Pat)}
message SchemasRequest {
  string catalog = 1;
  string schema_pattern = 2;
  string connection_id = 3;
}

// Request for Request for Meta#getTables(String, org.apache.calcite.avatica.Meta.Pat,
//   org.apache.calcite.avatica.Meta.Pat, java.util.List)
message TablesRequest {
  string catalog = 1;
  string schema_pattern = 2;
  string table_name_pattern = 3;
  repeated string type_list = 4;
  bool has_type_list = 6; // Having an empty type_list is distinct from a null type_list
  string connection_id = 7;
}

// Request for Meta#getTableTypes()
message TableTypesRequest {
  string connection_id = 1;
}

// Request for Meta#getColumns(String, org.apache.calcite.avatica.Meta.Pat,
//   org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat).
message ColumnsRequest {
  string catalog = 1;
  string schema_pattern = 2;
  string table_name_pattern = 3;
  string column_name_pattern = 4;
  string connection_id = 5;
}

// Request for Meta#getTypeInfo()
message TypeInfoRequest {
  string connection_id = 1;
}

// Request for Meta#prepareAndExecute(Meta.StatementHandle, String, long, Meta.PrepareCallback)
message PrepareAndExecuteRequest {
  string connection_id = 1;
  string sql = 2;
  uint64 max_row_count = 3; // Deprecated
  uint32 statement_id = 4;
  int64 max_rows_total = 5; // The maximum number of rows that will be allowed for this query
  int32 first_frame_max_size = 6; // The maximum number of rows that will be returned in the
                                  // first Frame returned for this query.
}

// Request for Meta.prepare(Meta.ConnectionHandle, String, long)
message PrepareRequest {
  string connection_id = 1;
  string sql = 2;
  uint64 max_row_count = 3; // Deprecated
  int64 max_rows_total = 4; // The maximum number of rows that will be allowed for this query
}

// Request for Meta#fetch(Meta.StatementHandle, List, long, int)
message FetchRequest {
  string connection_id = 1;
  uint32 statement_id = 2;
  uint64 offset = 3;
  uint32 fetch_max_row_count = 4; // Maximum number of rows to be returned in the frame. Negative means no limit. Deprecated!
  int32 frame_max_size = 5;
}

// Request for Meta#createStatement(Meta.ConnectionHandle)
message CreateStatementRequest {
  string connection_id = 1;
}

// Request for Meta#closeStatement(Meta.StatementHandle)
message CloseStatementRequest {
  string connection_id = 1;
  uint32 statement_id = 2;
}

// Request for Meta#openConnection(Meta.ConnectionHandle, Map<String, String>)
message OpenConnectionRequest {
  string connection_id = 1;
  map<string, string> info = 2;
}

// Request for Meta#closeConnection(Meta.ConnectionHandle)
message CloseConnectionRequest {
  string connection_id = 1;
}

message ConnectionSyncRequest {
  string connection_id = 1;
  ConnectionProperties conn_props = 2;
}

// Request for Meta#execute(Meta.ConnectionHandle, list, long)
message ExecuteRequest {
  StatementHandle statementHandle = 1;
  repeated TypedValue parameter_values = 2;
  uint64 deprecated_first_frame_max_size = 3; // Deprecated, use the signed int instead.
  bool has_parameter_values = 4;
  int32 first_frame_max_size = 5; // The maximum number of rows to return in the first Frame
}


message SyncResultsRequest {
  string connection_id = 1;
  uint32 statement_id = 2;
  QueryState state = 3;
  uint64 offset = 4;
}

// Request to invoke a commit on a Connection
message CommitRequest {
  string connection_id = 1;
}

// Request to invoke rollback on a Connection
message RollbackRequest {
  string connection_id = 1;
}

// Request to prepare and execute a collection of sql statements.
message PrepareAndExecuteBatchRequest {
  string connection_id = 1;
  uint32 statement_id = 2;
  repeated string sql_commands = 3;
}

// Each command is a list of TypedValues
message UpdateBatch {
  repeated TypedValue parameter_values = 1;
}

message ExecuteBatchRequest {
  string connection_id = 1;
  uint32 statement_id = 2;
  repeated UpdateBatch updates = 3; // A batch of updates is a list<list<typevalue>>
}
