syntax = "proto3";

package tipb;

option java_multiple_files = true;
option java_package = "com.pingcap.tidb.tipb";


message ExplainData {
    ExplainOperator main = 1;
    repeated ExplainOperator ctes = 2;
    // with_runtime_stats represents if runtime stats are available.
    // If not available, the act_rows, *_exec_info, memory_bytes and disk_bytes should not be used.
    bool with_runtime_stats = 3;
    // If discarded_due_to_too_long is true. The main and ctes fields should be empty and should not be used.
    // This field can be changed to a enum or int if we need to represent more states in the future.
    bool discarded_due_to_too_long = 4;
}

message ExplainOperator {
    string name = 1;
    repeated ExplainOperator children = 2;

    repeated OperatorLabel labels = 3;

    // the cost of the current operator
    double cost = 4;

    double est_rows = 5;
    uint64 act_rows = 6;

    TaskType task_type = 7;
    StoreType store_type = 8;

    // The XXXReader/XXXScan/MemTable/PointGet/BatchPointGet may use this
    repeated AccessObject access_objects = 9;

    string operator_info = 10;
    string root_basic_exec_info = 11;
    repeated string root_group_exec_info = 12;
    string cop_exec_info = 13;

    // memory_bytes and disk_bytes are expected to be displayed as "N/A" when they are -1,
    // this will be consistent with the result of EXPLAIN ANALYZE.
    int64 memory_bytes = 14;
    int64 disk_bytes = 15;
    
    string brief_name = 16;
    string brief_operator_info = 17;
}

message AccessObject {
    oneof access_object {
        ScanAccessObject scan_object = 1;
        DynamicPartitionAccessObjects dynamic_partition_objects = 2;
        string other_object = 3;
    }
}

message DynamicPartitionAccessObjects {
    repeated DynamicPartitionAccessObject objects = 1;
}

// DynamicPartitionAccessObject represents the partitions accessed by the children of this operator.
message DynamicPartitionAccessObject {
    string database = 1;
    string table = 2;
    bool all_partitions = 3;
    repeated string partitions = 4;
}

// ScanAccessObject represents the access to a single table. It may contain multiple indexes and multiple partitions.
message ScanAccessObject {
    string database = 1;
    string table = 2;
    repeated IndexAccess indexes = 3;
    repeated string partitions = 4;
}

message IndexAccess {
    string name = 1;
    repeated string cols = 2;
    bool is_clustered_index = 3;
}

enum TaskType {
    unknown = 0;
    root = 1;
    cop = 2;
    batchCop = 3;
    mpp = 4;
}

enum StoreType {
    unspecified = 0;
    tidb = 1;
    tikv = 2;
    tiflash = 3;
}

enum OperatorLabel {
    // empty is not expected to be used.
    empty = 0;
    buildSide = 1;
    probeSide = 2;
    seedPart = 3;
    recursivePart = 4;
}
