// 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 impala;

import "common.proto";
import "row_batch.proto";

// All fields are required in V1.
message TransmitDataRequestPB {
  // The fragment instance id of the receiver.
  optional UniqueIdPB dest_fragment_instance_id = 1;

  // Sender instance id, unique within a fragment.
  optional int32 sender_id = 2;

  // PlanNodeId of the exchange node which owns the receiver.
  optional int32 dest_node_id = 3;

  // The header which contains the meta-data of the row batch.
  optional RowBatchHeaderPB row_batch_header = 4;

  // The sidecar index of tuple offsets' buffer which is an array of int32 containing the
  // offsets of tuples into the buffer pointed to by tuple data's sidecar below. There are
  // num_rows * num_tuples_per_row offsets in total. An offset of -1 records a NULL.
  optional int32 tuple_offsets_sidecar_idx = 5;

  // The sidecar index of the tuple's data which is a (compressed) row batch.
  // The details of the row batch (e.g. # of rows) is in 'row_batch_header' above.
  optional int32 tuple_data_sidecar_idx = 6;
}

// All fields are required in V1.
message TransmitDataResponsePB {
  // Status::OK() on success; Error status on failure.
  optional StatusPB status = 1;
}

// All fields are required in V1.
message EndDataStreamRequestPB {
  // The fragment instance id of the receiver.
  optional UniqueIdPB dest_fragment_instance_id = 1;

  // Sender instance id, unique within a fragment.
  optional int32 sender_id = 2;

  // PlanNodeId of the exchange node which owns the receiver.
  optional int32 dest_node_id = 3;
}

// All fields are required in V1.
message EndDataStreamResponsePB {
  optional StatusPB status = 1;
}

// Handles data transmission between fragment instances.
service DataStreamService {
  // Called by sender to transmit a single row batch. Returns error indication
  // if params.fragmentId or params.destNodeId are unknown or if data couldn't
  // be read.
  rpc TransmitData(TransmitDataRequestPB) returns (TransmitDataResponsePB);

  // Called by a sender to close the channel between fragment instances.
  rpc EndDataStream(EndDataStreamRequestPB) returns (EndDataStreamResponsePB);
}
