//
// 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.
//

package exec.shared;

option java_package = "org.apache.drill.exec.proto";
option java_outer_classname = "UserBitShared";
option optimize_for = SPEED;

import "Types.proto";
import "Coordination.proto";
import "SchemaDef.proto";

enum RpcChannel {
  BIT_CONTROL = 0;
  BIT_DATA = 1;
  USER = 2;
}

enum QueryType {
  SQL = 1;
  LOGICAL = 2;
  PHYSICAL = 3;
  EXECUTION = 4;

  /* Input is a prepared statement */
  PREPARED_STATEMENT = 5;
}

message UserCredentials {
  optional string user_name = 1;
}

message QueryId {
  optional sfixed64 part1 = 1;
  optional sfixed64 part2 = 2;
}

message DrillPBError{
  enum ErrorType {
    /* equivalent to SQLClientInfoException
     * - handshake version error
     * - invalid schema
     */
    CONNECTION = 0;
    /* equivalent to SQLRecoverableException
     * - corrupt files: can't be read. FS read error
     * - parsing error due to incomplete or incorrectly written records
     */
    DATA_READ = 1;
    /* equivalent to SQLDataException
     * - data type unsupported by format
     */
    DATA_WRITE = 2;
    /* equivalent to SQLDataException
     * - Casting errors
     * - function not found for incoming types after implicit casting
     * - Flatten misuse
     */
    FUNCTION = 3;
    /* equivalent to SQLSyntaxErrorException
     * - typos
     * - missing table
     * - SQL keyword misuse
     * - function names/resolution
     */
    PARSE = 4;
    /* equivalent to SQLInvalidAuthorizationSpecException
     */
    PERMISSION = 5;
    /* equivalent to SQLNonTransientException
     */
    PLAN = 6;
    /* equivalent to SQLRecoverableException or SQLTransientException
     * - Recoverable: memory, disk
     * - Transient: network
     */
    RESOURCE = 7;
    /* equivalent to SQLNonTransientException.
     * - unexpected internal state
     * - uncategorized operation
     * general user action is to contact the Drill team for
     * assistance
     */
    SYSTEM = 8;
    /* equivalent to SQLFeatureNotSupportedException
     * - unimplemented feature, option, or execution path
     * - schema change in operator that does not support it
     */
    UNSUPPORTED_OPERATION = 9;
    /* SQL validation exception
     * - invalid schema path
     * - invalid entries in SQL tree
     */
    VALIDATION = 10;
    /* Execution exception
     *  - Internal errors not related to bad code
     */
    EXECUTION_ERROR = 11;
    /* Internal exception
     *  - Failed assertions
     *  - Other "this should not happen" cases
     */
    INTERNAL_ERROR = 12;
    /* Unspecified exception
     *  - Exception caught but cause is unknown
     * Indicates code that needs revisiting to move error reporting
     * closer to the cause.
     */
    UNSPECIFIED_ERROR = 13;
    /* Plugin exception
     * - A failure has occurred within a plugin.
     * Indicates that a plugin is misconfigured or contains a bug.
     */
    PLUGIN = 14;
  }
  optional string error_id = 1; // for debug tracing purposes
  optional DrillbitEndpoint endpoint = 2;
  optional ErrorType error_type = 3;
  optional string message = 4;
  optional ExceptionWrapper exception = 5;
  repeated ParsingError parsing_error = 6; //optional, used when providing location of error within a piece of text.
}

message ExceptionWrapper {
  optional string exception_class = 1;
  optional string message = 2;
  repeated StackTraceElementWrapper stack_trace = 3;
  optional ExceptionWrapper cause = 4;
}

message StackTraceElementWrapper {
    optional string class_name = 1;
    optional string file_name = 2;
    optional int32 line_number = 3;
    optional string method_name = 4;
    optional bool is_native_method = 5;
}

message ParsingError{
  optional int32 start_column = 2;
  optional int32 start_row = 3;
  optional int32 end_column = 4;
  optional int32 end_row = 5;
}

message RecordBatchDef {
  optional int32 record_count = 1;
  repeated SerializedField field = 2;
  optional bool carries_two_byte_selection_vector = 3;
  // The value is set when result set is disabled and its value corresponds to number
  // of rows affected by query (see JDBC java.sql.ResultSet#getUpdateCount())
  optional int32 affected_rows_count = 4;
}

message NamePart{

  enum Type{
    NAME = 0;
    ARRAY = 1;
  }

  optional Type type = 1;
  optional string name = 2;
  optional NamePart child = 3;
}

message SerializedField {
  optional common.MajorType major_type = 1; // the type associated with this field.
  optional NamePart name_part = 2;
  repeated SerializedField child = 3; // only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST

  optional int32 value_count = 4;
  optional int32 var_byte_length = 5;
  optional int32 buffer_length = 7;
}

message NodeStatus {
	optional int32 node_id = 1;
	optional int64 memory_footprint = 2;
}

/*
 * Used by the server to report informations about the query state to the client
 */
message QueryResult {
	enum QueryState {
	  STARTING = 0; // query has been scheduled for execution. This is post-enqueued.
	  RUNNING = 1;
	  COMPLETED = 2; // query has completed successfully
	  CANCELED = 3; // query has been cancelled, and all cleanup is complete
	  FAILED = 4;
	  CANCELLATION_REQUESTED = 5; // cancellation has been requested, and is being processed
	  ENQUEUED = 6; // query has been enqueued. this is pre-starting.
	  PREPARING = 7; // query is at preparation stage, foreman is initializing
	  PLANNING = 8; // query is at planning stage (includes logical or / and physical planning)
	}

	optional QueryState query_state = 1;
	optional QueryId query_id = 2;
	repeated DrillPBError error = 3;
}

/*
 * Used by the server when sending query result data batches to the client
 */
message QueryData {
  optional QueryId query_id = 1;
  optional int32 row_count = 2;
  optional RecordBatchDef def = 3;
  optional int32 affected_rows_count = 4;
}

message QueryInfo {
  optional string query = 1;
  optional int64 start = 2;
  optional QueryResult.QueryState state = 3;
  optional string user = 4 [default = "-"];
  optional DrillbitEndpoint foreman = 5;
  optional string options_json = 6;
  optional double total_cost = 7;
  optional string queue_name = 8 [default = "-"];
}

message QueryProfile {
  optional QueryId id = 1;
  optional QueryType type = 2;
  optional int64 start = 3;
  optional int64 end = 4;
  optional string query = 5;
  optional string plan = 6;
  optional DrillbitEndpoint foreman = 7;
  optional QueryResult.QueryState state = 8;
  optional int32 total_fragments = 9;
  optional int32 finished_fragments = 10;
  repeated MajorFragmentProfile fragment_profile = 11;
  optional string user = 12 [default = "-"];
  optional string error = 13;
  optional string verboseError = 14;
  optional string error_id = 15;
  optional string error_node = 16;
  optional string options_json = 17;
  optional int64 planEnd = 18;
  optional int64 queueWaitEnd = 19;
  optional double total_cost = 20;
  optional string queue_name = 21 [default = "-"];
  optional string queryId = 22;
  optional int32 autoLimit = 23;
  repeated string scanned_plugins = 24;
}

message MajorFragmentProfile {
  optional int32 major_fragment_id = 1;
  repeated MinorFragmentProfile minor_fragment_profile = 2;
}

message MinorFragmentProfile {
  optional FragmentState state = 1;
  optional DrillPBError error = 2;
  optional int32 minor_fragment_id = 3;
  repeated OperatorProfile operator_profile = 4;
  optional int64 start_time = 5;
  optional int64 end_time = 6;
  optional int64 memory_used = 7;
  optional int64 max_memory_used = 8;
  optional DrillbitEndpoint endpoint = 9;
  optional int64 last_update = 10;
  optional int64 last_progress = 11;
}

message OperatorProfile {
  repeated StreamProfile input_profile = 1;
  optional int32 operator_id = 3;
  optional int32 operator_type = 4 [deprecated = true];
  optional int64 setup_nanos = 5;
  optional int64 process_nanos = 6;
  optional int64 peak_local_memory_allocated = 7;
  repeated MetricValue metric = 8;
  optional int64 wait_nanos = 9;
  optional string operator_type_name = 10;
}

message StreamProfile {
  optional int64 records = 1;
  optional int64 batches = 2;
  optional int64 schemas = 3;
}

message MetricValue {
  optional int32 metric_id = 1;
  optional int64 long_value = 2;
  optional double double_value = 3;
}

enum FragmentState {
  SENDING = 0;
  AWAITING_ALLOCATION = 1;
  RUNNING = 2;
  FINISHED = 3;
  CANCELLED = 4;
  FAILED = 5;
  CANCELLATION_REQUESTED = 6;
}

/* Registry that contains list of jars, each jar contains its name and list of function signatures.
Structure example:
REGISTRY    -> Jar1.jar   -> upper(VARCHAR-REQUIRED)
                          -> upper(VARCHAR-OPTIONAL)

            -> Jar2.jar   -> lower(VARCHAR-REQUIRED)
                          -> lower(VARCHAR-OPTIONAL)
*/
message Registry {
  repeated Jar jar = 1;
}

/* Jar contains jar name and list of function signatures.
 Function signature is concatenation of function name and its input parameters. */
message Jar {
  optional string name = 1;
  repeated string function_signature = 2;
}

enum SaslStatus {
  SASL_UNKNOWN = 0;
  SASL_START = 1;
  SASL_IN_PROGRESS = 2;
  SASL_SUCCESS = 3;
  SASL_FAILED = 4;
}

message SaslMessage {
  optional string mechanism = 1;
  optional bytes data = 2;
  optional SaslStatus status = 3;
}
