blob: 8868d456a3dba031a3651bc1873cf66c53bfafd4 [file]
// 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.
#include <gtest/gtest.h>
#include <memory>
#include <vector>
#include "common/status.h"
#include "exec/operator/exchange_sink_buffer.h"
#include "exec/operator/exchange_sink_operator.h"
#include "exec/sink/writer/vhive_utils.h"
#include "runtime/runtime_state.h"
namespace doris {
#define FAIL_IF_ERROR_OR_CATCH_EXCEPTION(stmt) \
do { \
try { \
{ \
Status _status_ = (stmt); \
if (UNLIKELY(!_status_.ok())) { \
EXPECT_TRUE(false) << _status_.to_string(); \
} \
} \
} catch (const doris::Exception& e) { \
EXPECT_TRUE(false) << e.what(); \
} \
} while (0)
class TQueryOptionsBuilder {
public:
explicit TQueryOptionsBuilder() : _query_options() {}
TQueryOptionsBuilder& set_batch_size(int batch_size) {
_query_options.batch_size = batch_size;
return *this;
}
TQueryOptionsBuilder& set_execution_timeout(int execution_timeout) {
_query_options.execution_timeout = execution_timeout;
return *this;
}
TQueryOptionsBuilder& set_mem_limit(int64_t mem_limit) {
_query_options.mem_limit = mem_limit;
return *this;
}
TQueryOptionsBuilder& set_query_type(TQueryType::type& query_type) {
_query_options.query_type = query_type;
return *this;
}
TQueryOptionsBuilder& set_be_exec_version(int be_exec_version) {
_query_options.be_exec_version = be_exec_version;
return *this;
}
TQueryOptionsBuilder& set_enable_local_exchange(bool enable_local_exchange) {
_query_options.__set_enable_local_exchange(enable_local_exchange);
return *this;
}
TQueryOptionsBuilder& set_enable_local_shuffle(bool enable_local_shuffle) {
_query_options.__set_enable_local_shuffle(enable_local_shuffle);
return *this;
}
TQueryOptionsBuilder& set_enable_reserve_memory(bool enable_reserve_memory) {
_query_options.__set_enable_reserve_memory(enable_reserve_memory);
return *this;
}
TQueryOptionsBuilder& set_runtime_filter_wait_infinitely(bool runtime_filter_wait_infinitely) {
_query_options.__set_runtime_filter_wait_infinitely(runtime_filter_wait_infinitely);
return *this;
}
TQueryOptionsBuilder& set_runtime_filter_max_in_num(int64_t runtime_filter_max_in_num) {
_query_options.__set_runtime_filter_max_in_num(runtime_filter_max_in_num);
return *this;
}
TQueryOptionsBuilder& set_runtime_bloom_filter_min_size(int64_t runtime_bloom_filter_min_size) {
_query_options.__set_runtime_bloom_filter_min_size(runtime_bloom_filter_min_size);
return *this;
}
TQueryOptionsBuilder& set_runtime_bloom_filter_max_size(int64_t runtime_bloom_filter_max_size) {
_query_options.__set_runtime_bloom_filter_max_size(runtime_bloom_filter_max_size);
return *this;
}
TQueryOptionsBuilder& set_enable_spill(int64_t enable_spill) {
_query_options.__set_enable_spill(enable_spill);
return *this;
}
TQueryOptions& build() { return _query_options; }
TQueryOptionsBuilder(const TQueryOptionsBuilder&) = delete;
void operator=(const TQueryOptionsBuilder&) = delete;
private:
TQueryOptions _query_options;
};
class TPlanNodeBuilder {
public:
explicit TPlanNodeBuilder(TPlanNodeId node_id, TPlanNodeType::type node_type,
int num_children = 0, int64_t limit = -1, bool compact_data = true)
: _plan_node() {
_plan_node.node_id = node_id;
_plan_node.node_type = node_type;
_plan_node.num_children = num_children;
_plan_node.limit = limit;
_plan_node.compact_data = compact_data;
}
TPlanNodeBuilder& set_is_serial_operator(bool is_serial_operator) {
_plan_node.__set_is_serial_operator(is_serial_operator);
return *this;
}
TPlanNodeBuilder& set_exchange_node(TExchangeNode& node) {
_plan_node.__set_exchange_node(node);
return *this;
}
TPlanNodeBuilder& set_hash_join_node(THashJoinNode& node) {
_plan_node.__set_hash_join_node(node);
return *this;
}
TPlanNodeBuilder& append_row_tuples(TTupleId tuple_id, bool nullable) {
_plan_node.row_tuples.emplace_back(tuple_id);
return *this;
}
TPlanNodeBuilder& set_output_tuple_id(TTupleId output_tuple_id) {
_plan_node.__set_output_tuple_id(output_tuple_id);
return *this;
}
TPlanNodeBuilder& append_projections(TExpr& projections) {
_plan_node.__isset.projections = true;
_plan_node.projections.push_back(projections);
return *this;
}
TPlanNodeBuilder& append_runtime_filters(TRuntimeFilterDesc& runtime_filter) {
_plan_node.__isset.runtime_filters = true;
_plan_node.runtime_filters.push_back(runtime_filter);
return *this;
}
TPlanNode& build() { return _plan_node; }
TPlanNodeBuilder(const TPlanNodeBuilder&) = delete;
void operator=(const TPlanNodeBuilder&) = delete;
private:
TPlanNode _plan_node;
};
class TExchangeNodeBuilder {
public:
explicit TExchangeNodeBuilder() : _plan_node() {}
TExchangeNodeBuilder& set_partition_type(TPartitionType::type partition_type) {
_plan_node.__set_partition_type(partition_type);
return *this;
}
TExchangeNodeBuilder& append_input_row_tuples(TTupleId tuple_id) {
_plan_node.input_row_tuples.emplace_back(tuple_id);
return *this;
}
TExchangeNode& build() { return _plan_node; }
TExchangeNodeBuilder(const TExchangeNodeBuilder&) = delete;
void operator=(const TExchangeNodeBuilder&) = delete;
private:
TExchangeNode _plan_node;
};
class TDataSinkBuilder {
public:
explicit TDataSinkBuilder(TDataSinkType::type type) : _sink() { _sink.type = type; }
TDataSinkBuilder& set_stream_sink(TDataStreamSink& stream_sink) {
_sink.stream_sink = stream_sink;
return *this;
}
TDataSink& build() { return _sink; }
TDataSinkBuilder(const TDataSinkBuilder&) = delete;
void operator=(const TDataSinkBuilder&) = delete;
private:
TDataSink _sink;
};
class TDataStreamSinkBuilder {
public:
explicit TDataStreamSinkBuilder(TPlanNodeId dest_node_id, TDataPartition output_partition)
: _sink() {
_sink.dest_node_id = dest_node_id;
_sink.output_partition = output_partition;
}
TDataStreamSink& build() { return _sink; }
TDataStreamSinkBuilder(const TDataStreamSinkBuilder&) = delete;
void operator=(const TDataStreamSinkBuilder&) = delete;
private:
TDataStreamSink _sink;
};
class TPlanFragmentDestinationBuilder {
public:
explicit TPlanFragmentDestinationBuilder(TUniqueId fragment_instance_id, TNetworkAddress server,
TNetworkAddress brpc_server)
: _dest() {
_dest.fragment_instance_id = fragment_instance_id;
_dest.server = server;
_dest.brpc_server = brpc_server;
}
TPlanFragmentDestination& build() { return _dest; }
TPlanFragmentDestinationBuilder(const TPlanFragmentDestinationBuilder&) = delete;
void operator=(const TPlanFragmentDestinationBuilder&) = delete;
private:
TPlanFragmentDestination _dest;
};
class TTypeDescBuilder {
public:
explicit TTypeDescBuilder() : _desc() {
_desc.__set_result_is_nullable(false);
_desc.__set_is_nullable(false);
}
TTypeDescBuilder& set_types(TTypeNode type_node) {
_desc.types.push_back(type_node);
return *this;
}
TTypeDesc& build() { return _desc; }
TTypeDescBuilder(const TTypeDescBuilder&) = delete;
void operator=(const TTypeDescBuilder&) = delete;
private:
TTypeDesc _desc;
};
class TTypeNodeBuilder {
public:
explicit TTypeNodeBuilder() : _desc() {}
TTypeNodeBuilder& set_type(TTypeNodeType::type type) {
_desc.type = type;
return *this;
}
TTypeNodeBuilder& set_scalar_type(TPrimitiveType::type type, int len = 0, int precision = 0,
int scale = 0) {
TScalarType scalar_type;
scalar_type.type = type;
scalar_type.__set_len(len);
scalar_type.__set_precision(precision);
scalar_type.__set_scale(scale);
_desc.__set_scalar_type(scalar_type);
return *this;
}
TTypeNode& build() { return _desc; }
TTypeNodeBuilder(const TTypeNodeBuilder&) = delete;
void operator=(const TTypeNodeBuilder&) = delete;
private:
TTypeNode _desc;
};
class TDataPartitionBuilder {
public:
explicit TDataPartitionBuilder(TPartitionType::type type) : _partition() {
_partition.type = type;
}
TDataPartitionBuilder& append_partition_exprs(TExpr expr) {
_partition.partition_exprs.push_back(expr);
return *this;
}
TDataPartitionBuilder& append_partition_infos(TRangePartition info) {
_partition.partition_infos.push_back(info);
return *this;
}
TDataPartition& build() { return _partition; }
TDataPartitionBuilder(const TDataPartitionBuilder&) = delete;
void operator=(const TDataPartitionBuilder&) = delete;
private:
TDataPartition _partition;
};
class THashJoinNodeBuilder {
public:
explicit THashJoinNodeBuilder(TJoinOp::type join_op,
std::vector<TEqJoinCondition>& eq_join_conjuncts)
: _plan_node() {
_plan_node.__set_join_op(join_op);
_plan_node.__set_eq_join_conjuncts(eq_join_conjuncts);
}
explicit THashJoinNodeBuilder(TJoinOp::type join_op,
std::vector<TEqJoinCondition>&& eq_join_conjuncts)
: _plan_node() {
_plan_node.__set_join_op(join_op);
_plan_node.__set_eq_join_conjuncts(eq_join_conjuncts);
}
THashJoinNodeBuilder& set_is_broadcast_join(bool is_broadcast_join) {
_plan_node.__set_is_broadcast_join(is_broadcast_join);
return *this;
}
THashJoinNodeBuilder& append_vintermediate_tuple_id_list(TTupleId vintermediate_tuple_id_list) {
_plan_node.vintermediate_tuple_id_list.push_back(vintermediate_tuple_id_list);
return *this;
}
THashJoinNodeBuilder& set_dist_type(TJoinDistributionType::type dist_type) {
_plan_node.__set_dist_type(dist_type);
return *this;
}
THashJoinNode& build() { return _plan_node; }
THashJoinNodeBuilder(const THashJoinNodeBuilder&) = delete;
void operator=(const THashJoinNodeBuilder&) = delete;
private:
THashJoinNode _plan_node;
};
class TSlotRefBuilder {
public:
explicit TSlotRefBuilder(TSlotId slot_id, TTupleId tuple_id) : _slot_ref() {
_slot_ref.__set_slot_id(slot_id);
_slot_ref.__set_tuple_id(tuple_id);
}
TSlotRefBuilder& set_col_unique_id(int col_unique_id) {
_slot_ref.__set_col_unique_id(col_unique_id);
return *this;
}
TSlotRef& build() { return _slot_ref; }
TSlotRefBuilder(const TSlotRefBuilder&) = delete;
void operator=(const TSlotRefBuilder&) = delete;
private:
TSlotRef _slot_ref;
};
class TExprNodeBuilder {
public:
explicit TExprNodeBuilder(TExprNodeType::type node_type, TTypeDesc& type, int num_children,
TExprOpcode::type opcode = TExprOpcode::INVALID_OPCODE)
: _expr_node() {
_expr_node.__set_node_type(node_type);
_expr_node.__set_type(type);
_expr_node.__set_num_children(num_children);
_expr_node.__set_opcode(opcode);
_expr_node.__set_is_nullable(false);
}
explicit TExprNodeBuilder(TExprNodeType::type node_type, TTypeDesc&& type, int num_children,
TExprOpcode::type opcode = TExprOpcode::INVALID_OPCODE)
: _expr_node() {
_expr_node.__set_node_type(node_type);
_expr_node.__set_type(type);
_expr_node.__set_num_children(num_children);
_expr_node.__set_opcode(opcode);
}
TExprNodeBuilder& set_slot_ref(TSlotRef& slot_ref) {
_expr_node.__set_slot_ref(slot_ref);
return *this;
}
TExprNode& build() { return _expr_node; }
TExprNodeBuilder(const TExprNodeBuilder&) = delete;
void operator=(const TExprNodeBuilder&) = delete;
private:
TExprNode _expr_node;
};
class TExprBuilder {
public:
explicit TExprBuilder() : _expr() {}
TExprBuilder& append_nodes(TExprNode& node) {
_expr.nodes.push_back(node);
return *this;
}
TExpr& build() { return _expr; }
TExprBuilder(const TExprBuilder&) = delete;
void operator=(const TExprBuilder&) = delete;
private:
TExpr _expr;
};
class TEqJoinConditionBuilder {
public:
explicit TEqJoinConditionBuilder(TExpr& left, TExpr& right,
TExprOpcode::type opcode = TExprOpcode::EQ)
: _eq_conjuncts() {
_eq_conjuncts.__set_left(left);
_eq_conjuncts.__set_right(right);
_eq_conjuncts.__set_opcode(opcode);
}
TEqJoinCondition& build() { return _eq_conjuncts; }
TEqJoinConditionBuilder(const TEqJoinConditionBuilder&) = delete;
void operator=(const TEqJoinConditionBuilder&) = delete;
private:
TEqJoinCondition _eq_conjuncts;
};
class TRuntimeFilterParamsBuilder {
public:
explicit TRuntimeFilterParamsBuilder(
TNetworkAddress runtime_filter_merge_addr = TNetworkAddress(),
std::map<int, std::vector<TRuntimeFilterTargetParams>> rid_to_target_param = {},
std::map<int, int> runtime_filter_builder_num = {},
std::map<int, std::vector<TRuntimeFilterTargetParamsV2>> rid_to_target_paramv2 = {})
: _params() {
_params.__set_runtime_filter_merge_addr(runtime_filter_merge_addr);
_params.__set_rid_to_target_param(rid_to_target_param);
_params.__set_runtime_filter_builder_num(runtime_filter_builder_num);
_params.__set_rid_to_target_paramv2(rid_to_target_paramv2);
}
TRuntimeFilterParamsBuilder& add_rid_to_runtime_filter(
int rid, TRuntimeFilterDesc param = TRuntimeFilterDesc()) {
_params.__isset.rid_to_runtime_filter = true;
_params.rid_to_runtime_filter[rid] = param;
return *this;
}
TRuntimeFilterParamsBuilder& add_runtime_filter_builder_num(int rid, int builder_num) {
_params.runtime_filter_builder_num[rid] = builder_num;
return *this;
}
TRuntimeFilterParamsBuilder& add_rid_to_target_paramv2(
int rid, std::vector<TRuntimeFilterTargetParamsV2> target_paramv2 = {}) {
_params.rid_to_target_paramv2[rid] = target_paramv2;
return *this;
}
TRuntimeFilterParams& build() { return _params; }
TRuntimeFilterParamsBuilder(const TRuntimeFilterParamsBuilder&) = delete;
void operator=(const TRuntimeFilterParamsBuilder&) = delete;
private:
TRuntimeFilterParams _params;
};
class TRuntimeFilterDescBuilder {
public:
static TExpr get_default_expr() {
return TExprBuilder()
.append_nodes(
TExprNodeBuilder(
TExprNodeType::SLOT_REF,
TTypeDescBuilder()
.set_types(TTypeNodeBuilder()
.set_type(TTypeNodeType::SCALAR)
.set_scalar_type(TPrimitiveType::INT)
.build())
.build(),
0)
.set_slot_ref(TSlotRefBuilder(0, 0).build())
.build())
.build();
}
explicit TRuntimeFilterDescBuilder(
int filter_id, TExpr& src_expr, int expr_order,
std::map<TPlanNodeId, TExpr> planId_to_target_expr, bool is_broadcast_join = false,
bool has_local_targets = true, bool has_remote_targets = false,
TRuntimeFilterType::type type = TRuntimeFilterType::IN_OR_BLOOM) {
_desc.__set_filter_id(filter_id);
_desc.__set_src_expr(src_expr);
_desc.__set_expr_order(expr_order);
_desc.__set_planId_to_target_expr(planId_to_target_expr);
_desc.__set_is_broadcast_join(is_broadcast_join);
_desc.__set_has_local_targets(has_local_targets);
_desc.__set_has_remote_targets(has_remote_targets);
_desc.__set_type(type);
}
explicit TRuntimeFilterDescBuilder(
int filter_id = 0, TExpr src_expr = get_default_expr(), int expr_order = 0,
std::map<TPlanNodeId, TExpr> planId_to_target_expr = std::map<TPlanNodeId, TExpr> {}) {
_desc.__set_filter_id(filter_id);
_desc.__set_src_expr(src_expr);
_desc.__set_expr_order(expr_order);
_desc.__set_planId_to_target_expr(planId_to_target_expr);
_desc.__set_is_broadcast_join(false);
_desc.__set_has_local_targets(true);
_desc.__set_has_remote_targets(false);
_desc.__set_null_aware(false);
_desc.__set_type(TRuntimeFilterType::IN_OR_BLOOM);
}
TRuntimeFilterDescBuilder& set_bloom_filter_size_bytes(int64_t bloom_filter_size_bytes) {
_desc.__set_bloom_filter_size_bytes(bloom_filter_size_bytes);
return *this;
}
TRuntimeFilterDescBuilder& set_is_broadcast_join(bool is_broadcast_join) {
_desc.__set_is_broadcast_join(is_broadcast_join);
return *this;
}
TRuntimeFilterDescBuilder& set_mode(bool local) {
_desc.__set_has_local_targets(local);
_desc.__set_has_remote_targets(!local);
return *this;
}
TRuntimeFilterDescBuilder& add_planId_to_target_expr(int node_id,
TExpr expr = get_default_expr()) {
_desc.planId_to_target_expr[node_id] = expr;
return *this;
}
TRuntimeFilterDescBuilder& set_type(TRuntimeFilterType::type type) {
_desc.__set_type(type);
return *this;
}
TRuntimeFilterDescBuilder& set_build_bf_by_runtime_size(bool build_bf_by_runtime_size) {
_desc.__set_build_bf_by_runtime_size(build_bf_by_runtime_size);
return *this;
}
TRuntimeFilterDesc& build() { return _desc; }
TRuntimeFilterDescBuilder(const TRuntimeFilterDescBuilder&) = delete;
void operator=(const TRuntimeFilterDescBuilder&) = delete;
private:
TRuntimeFilterDesc _desc;
};
} // namespace doris