This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch branch-1.2-unstable in repository https://gitbox.apache.org/repos/asf/doris.git
commit f5ec89b45b5315a540573e473065fbba49bcd2a2 Author: Gabriel <gabrielleeb...@gmail.com> AuthorDate: Wed Nov 9 11:27:46 2022 +0800 [Compile](join) Boost compiling and linking (#14081) --- be/src/vec/exec/join/vhash_join_node.cpp | 264 +++++++++++++++++-------------- be/src/vec/exec/join/vhash_join_node.h | 60 +++---- 2 files changed, 163 insertions(+), 161 deletions(-) diff --git a/be/src/vec/exec/join/vhash_join_node.cpp b/be/src/vec/exec/join/vhash_join_node.cpp index 0b326db114..8c0d5b3f7a 100644 --- a/be/src/vec/exec/join/vhash_join_node.cpp +++ b/be/src/vec/exec/join/vhash_join_node.cpp @@ -58,8 +58,7 @@ struct ProcessHashTableBuild { _offset(offset), _build_side_compute_hash_timer(join_node->_build_side_compute_hash_timer) {} - template <bool need_null_map_for_build, bool ignore_null, bool build_unique, - bool has_runtime_filter, bool short_circuit_for_null> + template <bool ignore_null, bool short_circuit_for_null> void run(HashTableContext& hash_table_ctx, ConstNullMapPtr null_map, bool* has_null_key) { using KeyGetter = typename HashTableContext::State; using Mapped = typename HashTableContext::Mapped; @@ -76,14 +75,15 @@ struct ProcessHashTableBuild { SCOPED_TIMER(_join_node->_build_table_insert_timer); // only not build_unique, we need expanse hash table before insert data - if constexpr (!build_unique) { + if (!_join_node->_build_unique) { // _rows contains null row, which will cause hash table resize to be large. hash_table_ctx.hash_table.expanse_for_add_elem(_rows); } hash_table_ctx.hash_table.reset_resize_timer(); vector<int>& inserted_rows = _join_node->_inserted_rows[&_acquired_block]; - if constexpr (has_runtime_filter) { + bool has_runtime_filter = !_join_node->_runtime_filter_descs.empty(); + if (has_runtime_filter) { inserted_rows.reserve(_batch_size); } @@ -92,14 +92,14 @@ struct ProcessHashTableBuild { { SCOPED_TIMER(_build_side_compute_hash_timer); for (size_t k = 0; k < _rows; ++k) { - if constexpr (ignore_null && need_null_map_for_build) { + if constexpr (ignore_null) { if ((*null_map)[k]) { continue; } } // If apply short circuit strategy for null value (e.g. join operator is // NULL_AWARE_LEFT_ANTI_JOIN), we build hash table until we meet a null value. - if constexpr (short_circuit_for_null && need_null_map_for_build) { + if constexpr (short_circuit_for_null) { if ((*null_map)[k]) { DCHECK(has_null_key); *has_null_key = true; @@ -116,37 +116,52 @@ struct ProcessHashTableBuild { } } - for (size_t k = 0; k < _rows; ++k) { - if constexpr (ignore_null && need_null_map_for_build) { - if ((*null_map)[k]) { - continue; - } - } - - auto emplace_result = key_getter.emplace_key(hash_table_ctx.hash_table, - _build_side_hash_values[k], k, arena); - if (k + PREFETCH_STEP < _rows) { - key_getter.template prefetch_by_hash<false>( - hash_table_ctx.hash_table, _build_side_hash_values[k + PREFETCH_STEP]); - } + bool build_unique = _join_node->_build_unique; +#define EMPLACE_IMPL(stmt) \ + for (size_t k = 0; k < _rows; ++k) { \ + if constexpr (ignore_null) { \ + if ((*null_map)[k]) { \ + continue; \ + } \ + } \ + auto emplace_result = key_getter.emplace_key(hash_table_ctx.hash_table, \ + _build_side_hash_values[k], k, arena); \ + if (k + PREFETCH_STEP < _rows) { \ + key_getter.template prefetch_by_hash<false>( \ + hash_table_ctx.hash_table, _build_side_hash_values[k + PREFETCH_STEP]); \ + } \ + stmt; \ + } - if (emplace_result.is_inserted()) { - new (&emplace_result.get_mapped()) Mapped({k, _offset}); - if constexpr (has_runtime_filter) { - inserted_rows.push_back(k); - } - } else { - if constexpr (!build_unique) { - /// The first element of the list is stored in the value of the hash table, the rest in the pool. - emplace_result.get_mapped().insert({k, _offset}, _join_node->_arena); - if constexpr (has_runtime_filter) { + if (has_runtime_filter && build_unique) { + EMPLACE_IMPL( + if (emplace_result.is_inserted()) { + new (&emplace_result.get_mapped()) Mapped({k, _offset}); inserted_rows.push_back(k); - } - } else { - _skip_rows++; - } - } + } else { _skip_rows++; }); + } else if (has_runtime_filter && !build_unique) { + EMPLACE_IMPL( + if (emplace_result.is_inserted()) { + new (&emplace_result.get_mapped()) Mapped({k, _offset}); + inserted_rows.push_back(k); + } else { + emplace_result.get_mapped().insert({k, _offset}, _join_node->_arena); + inserted_rows.push_back(k); + }); + } else if (!has_runtime_filter && build_unique) { + EMPLACE_IMPL( + if (emplace_result.is_inserted()) { + new (&emplace_result.get_mapped()) Mapped({k, _offset}); + } else { _skip_rows++; }); + } else { + EMPLACE_IMPL( + if (emplace_result.is_inserted()) { + new (&emplace_result.get_mapped()) Mapped({k, _offset}); + } else { + emplace_result.get_mapped().insert({k, _offset}, _join_node->_arena); + }); } +#undef EMPLACE_IMPL COUNTER_UPDATE(_join_node->_build_table_expanse_timer, hash_table_ctx.hash_table.get_resize_timer_value()); @@ -197,9 +212,8 @@ private: HashJoinNode* _join_node; }; -template <class JoinOpType, bool ignore_null> -ProcessHashTableProbe<JoinOpType, ignore_null>::ProcessHashTableProbe(HashJoinNode* join_node, - int batch_size) +template <class JoinOpType> +ProcessHashTableProbe<JoinOpType>::ProcessHashTableProbe(HashJoinNode* join_node, int batch_size) : _join_node(join_node), _batch_size(batch_size), _build_blocks(join_node->_build_blocks), @@ -219,9 +233,9 @@ ProcessHashTableProbe<JoinOpType, ignore_null>::ProcessHashTableProbe(HashJoinNo _build_side_output_timer(join_node->_build_side_output_timer), _probe_side_output_timer(join_node->_probe_side_output_timer) {} -template <class JoinOpType, bool ignore_null> +template <class JoinOpType> template <bool have_other_join_conjunct> -void ProcessHashTableProbe<JoinOpType, ignore_null>::build_side_output_column( +void ProcessHashTableProbe<JoinOpType>::build_side_output_column( MutableColumns& mcol, int column_offset, int column_length, const std::vector<bool>& output_slot_flags, int size) { constexpr auto is_semi_anti_join = JoinOpType::value == TJoinOp::RIGHT_ANTI_JOIN || @@ -293,11 +307,11 @@ void ProcessHashTableProbe<JoinOpType, ignore_null>::build_side_output_column( } } -template <class JoinOpType, bool ignore_null> -template <bool have_other_join_conjunct> -void ProcessHashTableProbe<JoinOpType, ignore_null>::probe_side_output_column( +template <class JoinOpType> +void ProcessHashTableProbe<JoinOpType>::probe_side_output_column( MutableColumns& mcol, const std::vector<bool>& output_slot_flags, int size, - int last_probe_index, size_t probe_size, bool all_match_one) { + int last_probe_index, size_t probe_size, bool all_match_one, + bool have_other_join_conjunct) { auto& probe_block = _join_node->_probe_block; for (int i = 0; i < output_slot_flags.size(); ++i) { if (output_slot_flags[i]) { @@ -314,18 +328,19 @@ void ProcessHashTableProbe<JoinOpType, ignore_null>::probe_side_output_column( } } - if constexpr (JoinOpType::value == TJoinOp::RIGHT_OUTER_JOIN && !have_other_join_conjunct) { - _tuple_is_null_left_flags->resize_fill(size, 0); + if constexpr (JoinOpType::value == TJoinOp::RIGHT_OUTER_JOIN) { + if (!have_other_join_conjunct) { + _tuple_is_null_left_flags->resize_fill(size, 0); + } } } -template <class JoinOpType, bool ignore_null> -template <bool need_null_map_for_probe, typename HashTableType> -Status ProcessHashTableProbe<JoinOpType, ignore_null>::do_process(HashTableType& hash_table_ctx, - ConstNullMapPtr null_map, - MutableBlock& mutable_block, - Block* output_block, - size_t probe_rows) { +template <class JoinOpType> +template <bool need_null_map_for_probe, bool ignore_null, typename HashTableType> +Status ProcessHashTableProbe<JoinOpType>::do_process(HashTableType& hash_table_ctx, + ConstNullMapPtr null_map, + MutableBlock& mutable_block, + Block* output_block, size_t probe_rows) { auto& probe_index = _join_node->_probe_index; auto& probe_raw_ptrs = _join_node->_probe_columns; if (probe_index == 0 && _items_counts.size() < probe_rows) { @@ -470,7 +485,8 @@ Status ProcessHashTableProbe<JoinOpType, ignore_null>::do_process(HashTableType& JoinOpType::value != TJoinOp::RIGHT_ANTI_JOIN) { SCOPED_TIMER(_probe_side_output_timer); probe_side_output_column(mcol, _join_node->_left_output_slot_flags, current_offset, - last_probe_index, probe_index - last_probe_index, all_match_one); + last_probe_index, probe_index - last_probe_index, all_match_one, + false); } output_block->swap(mutable_block.to_block()); @@ -478,9 +494,9 @@ Status ProcessHashTableProbe<JoinOpType, ignore_null>::do_process(HashTableType& return Status::OK(); } -template <class JoinOpType, bool ignore_null> -template <bool need_null_map_for_probe, typename HashTableType> -Status ProcessHashTableProbe<JoinOpType, ignore_null>::do_process_with_other_join_conjuncts( +template <class JoinOpType> +template <bool need_null_map_for_probe, bool ignore_null, typename HashTableType> +Status ProcessHashTableProbe<JoinOpType>::do_process_with_other_join_conjuncts( HashTableType& hash_table_ctx, ConstNullMapPtr null_map, MutableBlock& mutable_block, Block* output_block, size_t probe_rows) { auto& probe_index = _join_node->_probe_index; @@ -618,9 +634,9 @@ Status ProcessHashTableProbe<JoinOpType, ignore_null>::do_process_with_other_joi } { SCOPED_TIMER(_probe_side_output_timer); - probe_side_output_column<true>(mcol, _join_node->_left_output_slot_flags, - current_offset, last_probe_index, - probe_index - last_probe_index, all_match_one); + probe_side_output_column(mcol, _join_node->_left_output_slot_flags, current_offset, + last_probe_index, probe_index - last_probe_index, + all_match_one, true); } output_block->swap(mutable_block.to_block()); @@ -765,11 +781,12 @@ Status ProcessHashTableProbe<JoinOpType, ignore_null>::do_process_with_other_joi } } -template <class JoinOpType, bool ignore_null> +template <class JoinOpType> template <typename HashTableType> -Status ProcessHashTableProbe<JoinOpType, ignore_null>::process_data_in_hashtable( - HashTableType& hash_table_ctx, MutableBlock& mutable_block, Block* output_block, - bool* eos) { +Status ProcessHashTableProbe<JoinOpType>::process_data_in_hashtable(HashTableType& hash_table_ctx, + MutableBlock& mutable_block, + Block* output_block, + bool* eos) { using Mapped = typename HashTableType::Mapped; if constexpr (std::is_same_v<Mapped, RowRefListWithFlag> || std::is_same_v<Mapped, RowRefListWithFlags>) { @@ -926,8 +943,6 @@ Status HashJoinNode::init(const TPlanNode& tnode, RuntimeState* state) { probe_not_ignore_null[conjuncts_index] = null_aware || (_probe_expr_ctxs.back()->root()->is_nullable() && probe_dispose_null); - _build_side_ignore_null |= (_join_op != TJoinOp::NULL_AWARE_LEFT_ANTI_JOIN && - !_store_null_in_hash_table.back()); conjuncts_index++; } for (size_t i = 0; i < _probe_expr_ctxs.size(); ++i) { @@ -1117,7 +1132,7 @@ Status HashJoinNode::get_next(RuntimeState* state, Block* output_block, bool* eo // so we have to initialize this flag by the first probe block. if (!_has_set_need_null_map_for_probe) { _has_set_need_null_map_for_probe = true; - _need_null_map_for_probe = _need_null_map<false>(_probe_block, res_col_ids); + _need_null_map_for_probe = _need_probe_null_map(_probe_block, res_col_ids); } if (_need_null_map_for_probe) { if (_null_map_column == nullptr) { @@ -1150,17 +1165,17 @@ Status HashJoinNode::get_next(RuntimeState* state, Block* output_block, bool* eo if (_probe_index < _probe_block.rows()) { DCHECK(_has_set_need_null_map_for_probe); - std::visit( - [&](auto&& arg, auto&& process_hashtable_ctx, auto have_other_join_conjunct, - auto need_null_map_for_probe) { - using HashTableProbeType = std::decay_t<decltype(process_hashtable_ctx)>; - if constexpr (!std::is_same_v<HashTableProbeType, std::monostate>) { - using HashTableCtxType = std::decay_t<decltype(arg)>; - if constexpr (have_other_join_conjunct) { + if (_have_other_join_conjunct) { + std::visit( + [&](auto&& arg, auto&& process_hashtable_ctx, auto need_null_map_for_probe, + auto ignore_null) { + using HashTableProbeType = std::decay_t<decltype(process_hashtable_ctx)>; + if constexpr (!std::is_same_v<HashTableProbeType, std::monostate>) { + using HashTableCtxType = std::decay_t<decltype(arg)>; if constexpr (!std::is_same_v<HashTableCtxType, std::monostate>) { st = process_hashtable_ctx .template do_process_with_other_join_conjuncts< - need_null_map_for_probe>( + need_null_map_for_probe, ignore_null>( arg, need_null_map_for_probe ? &_null_map_column->get_data() @@ -1170,25 +1185,37 @@ Status HashJoinNode::get_next(RuntimeState* state, Block* output_block, bool* eo LOG(FATAL) << "FATAL: uninited hash table"; } } else { + LOG(FATAL) << "FATAL: uninited hash probe"; + } + }, + _hash_table_variants, _process_hashtable_ctx_variants, + make_bool_variant(_need_null_map_for_probe), + make_bool_variant(_probe_ignore_null)); + } else { + std::visit( + [&](auto&& arg, auto&& process_hashtable_ctx, auto need_null_map_for_probe, + auto ignore_null) { + using HashTableProbeType = std::decay_t<decltype(process_hashtable_ctx)>; + if constexpr (!std::is_same_v<HashTableProbeType, std::monostate>) { + using HashTableCtxType = std::decay_t<decltype(arg)>; if constexpr (!std::is_same_v<HashTableCtxType, std::monostate>) { - st = process_hashtable_ctx - .template do_process<need_null_map_for_probe>( - arg, - need_null_map_for_probe - ? &_null_map_column->get_data() - : nullptr, - mutable_join_block, &temp_block, probe_rows); + st = process_hashtable_ctx.template do_process< + need_null_map_for_probe, ignore_null>( + arg, + need_null_map_for_probe ? &_null_map_column->get_data() + : nullptr, + mutable_join_block, &temp_block, probe_rows); } else { LOG(FATAL) << "FATAL: uninited hash table"; } + } else { + LOG(FATAL) << "FATAL: uninited hash probe"; } - } else { - LOG(FATAL) << "FATAL: uninited hash probe"; - } - }, - _hash_table_variants, _process_hashtable_ctx_variants, - make_bool_variant(_have_other_join_conjunct), - make_bool_variant(_need_null_map_for_probe)); + }, + _hash_table_variants, _process_hashtable_ctx_variants, + make_bool_variant(_need_null_map_for_probe), + make_bool_variant(_probe_ignore_null)); + } } else if (_probe_eos) { if (_is_right_semi_anti || (_is_outer_join && _join_op != TJoinOp::LEFT_OUTER_JOIN)) { std::visit( @@ -1426,28 +1453,32 @@ Status HashJoinNode::_do_evaluate(Block& block, std::vector<VExprContext*>& expr return Status::OK(); } -template <bool BuildSide> -bool HashJoinNode::_need_null_map(Block& block, const std::vector<int>& res_col_ids) { +bool HashJoinNode::_need_probe_null_map(Block& block, const std::vector<int>& res_col_ids) { DCHECK_EQ(_build_expr_ctxs.size(), _probe_expr_ctxs.size()); for (size_t i = 0; i < _build_expr_ctxs.size(); ++i) { if (!_is_null_safe_eq_join[i]) { auto column = block.get_by_position(res_col_ids[i]).column.get(); - if constexpr (BuildSide) { - if (check_and_get_column<ColumnNullable>(*column)) { - if (!_store_null_in_hash_table[i]) { - return true; - } - } - } else { - if (check_and_get_column<ColumnNullable>(*column)) { - return true; - } + if (check_and_get_column<ColumnNullable>(*column)) { + return true; } } } return false; } +void HashJoinNode::_set_build_ignore_flag(Block& block, const std::vector<int>& res_col_ids) { + DCHECK_EQ(_build_expr_ctxs.size(), _probe_expr_ctxs.size()); + for (size_t i = 0; i < _build_expr_ctxs.size(); ++i) { + if (!_is_null_safe_eq_join[i]) { + auto column = block.get_by_position(res_col_ids[i]).column.get(); + if (check_and_get_column<ColumnNullable>(*column)) { + _build_side_ignore_null |= (_join_op != TJoinOp::NULL_AWARE_LEFT_ANTI_JOIN && + !_store_null_in_hash_table[i]); + } + } + } +} + Status HashJoinNode::_process_build_block(RuntimeState* state, Block& block, uint8_t offset) { SCOPED_TIMER(_build_table_timer); size_t rows = block.rows(); @@ -1468,10 +1499,9 @@ Status HashJoinNode::_process_build_block(RuntimeState* state, Block& block, uin // so we have to initialize this flag by the first build block. if (!_has_set_need_null_map_for_build) { _has_set_need_null_map_for_build = true; - _need_null_map_for_build = - _short_circuit_for_null_in_build_side || _need_null_map<true>(block, res_col_ids); + _set_build_ignore_flag(block, res_col_ids); } - if (_need_null_map_for_build) { + if (_short_circuit_for_null_in_build_side || _build_side_ignore_null) { null_map_val = ColumnUInt8::create(); null_map_val->get_data().assign(rows, (uint8_t)0); } @@ -1489,27 +1519,24 @@ Status HashJoinNode::_process_build_block(RuntimeState* state, Block& block, uin }, _hash_table_variants); - bool has_runtime_filter = !_runtime_filter_descs.empty(); - std::visit( - [&](auto&& arg, auto has_null_value, auto build_unique, auto has_runtime_filter_value, - auto need_null_map_for_build, auto short_circuit_for_null_in_build_side) { + [&](auto&& arg, auto has_null_value, auto short_circuit_for_null_in_build_side) { using HashTableCtxType = std::decay_t<decltype(arg)>; if constexpr (!std::is_same_v<HashTableCtxType, std::monostate>) { ProcessHashTableBuild<HashTableCtxType> hash_table_build_process( rows, block, raw_ptrs, this, state->batch_size(), offset); - hash_table_build_process.template run<need_null_map_for_build, has_null_value, - build_unique, has_runtime_filter_value, - short_circuit_for_null_in_build_side>( - arg, need_null_map_for_build ? &null_map_val->get_data() : nullptr, - &_short_circuit_for_null_in_probe_side); + hash_table_build_process + .template run<has_null_value, short_circuit_for_null_in_build_side>( + arg, + has_null_value || short_circuit_for_null_in_build_side + ? &null_map_val->get_data() + : nullptr, + &_short_circuit_for_null_in_probe_side); } else { LOG(FATAL) << "FATAL: uninited hash table"; } }, _hash_table_variants, make_bool_variant(_build_side_ignore_null), - make_bool_variant(_build_unique), make_bool_variant(has_runtime_filter), - make_bool_variant(_need_null_map_for_build), make_bool_variant(_short_circuit_for_null_in_build_side)); return st; @@ -1640,13 +1667,12 @@ void HashJoinNode::_hash_table_init() { void HashJoinNode::_process_hashtable_ctx_variants_init(RuntimeState* state) { std::visit( - [&](auto&& join_op_variants, auto probe_ignore_null) { + [&](auto&& join_op_variants) { using JoinOpType = std::decay_t<decltype(join_op_variants)>; - _process_hashtable_ctx_variants - .emplace<ProcessHashTableProbe<JoinOpType, probe_ignore_null>>( - this, state->batch_size()); + _process_hashtable_ctx_variants.emplace<ProcessHashTableProbe<JoinOpType>>( + this, state->batch_size()); }, - _join_op_variants, make_bool_variant(_probe_ignore_null)); + _join_op_variants); } std::vector<uint16_t> HashJoinNode::_convert_block_to_null(Block& block) { diff --git a/be/src/vec/exec/join/vhash_join_node.h b/be/src/vec/exec/join/vhash_join_node.h index 7d29268b39..977edcb29c 100644 --- a/be/src/vec/exec/join/vhash_join_node.h +++ b/be/src/vec/exec/join/vhash_join_node.h @@ -183,7 +183,7 @@ using JoinOpVariants = class VExprContext; class HashJoinNode; -template <class JoinOpType, bool ignore_null> +template <class JoinOpType> struct ProcessHashTableProbe { ProcessHashTableProbe(HashJoinNode* join_node, int batch_size); @@ -192,22 +192,21 @@ struct ProcessHashTableProbe { void build_side_output_column(MutableColumns& mcol, int column_offset, int column_length, const std::vector<bool>& output_slot_flags, int size); - template <bool have_other_join_conjunct = false> void probe_side_output_column(MutableColumns& mcol, const std::vector<bool>& output_slot_flags, int size, int last_probe_index, size_t probe_size, - bool all_match_one); + bool all_match_one, bool have_other_join_conjunct); // Only process the join with no other join conjunt, because of no other join conjunt // the output block struct is same with mutable block. we can do more opt on it and simplify // the logic of probe // TODO: opt the visited here to reduce the size of hash table - template <bool need_null_map_for_probe, typename HashTableType> + template <bool need_null_map_for_probe, bool ignore_null, typename HashTableType> Status do_process(HashTableType& hash_table_ctx, ConstNullMapPtr null_map, MutableBlock& mutable_block, Block* output_block, size_t probe_rows); // In the presence of other join conjunt, the process of join become more complicated. // each matching join column need to be processed by other join conjunt. so the sturct of mutable block // and output block may be different // The output result is determined by the other join conjunt result and same_to_prev struct - template <bool need_null_map_for_probe, typename HashTableType> + template <bool need_null_map_for_probe, bool ignore_null, typename HashTableType> Status do_process_with_other_join_conjuncts(HashTableType& hash_table_ctx, ConstNullMapPtr null_map, MutableBlock& mutable_block, Block* output_block, @@ -242,40 +241,17 @@ struct ProcessHashTableProbe { using HashTableCtxVariants = std::variant< std::monostate, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::INNER_JOIN>, true>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::LEFT_SEMI_JOIN>, true>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::LEFT_ANTI_JOIN>, true>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::LEFT_OUTER_JOIN>, - true>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::FULL_OUTER_JOIN>, - true>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::RIGHT_OUTER_JOIN>, - true>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::CROSS_JOIN>, true>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::RIGHT_SEMI_JOIN>, - true>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::RIGHT_ANTI_JOIN>, - true>, - ProcessHashTableProbe< - std::integral_constant<TJoinOp::type, TJoinOp::NULL_AWARE_LEFT_ANTI_JOIN>, true>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::INNER_JOIN>, false>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::LEFT_SEMI_JOIN>, - false>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::LEFT_ANTI_JOIN>, - false>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::LEFT_OUTER_JOIN>, - false>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::FULL_OUTER_JOIN>, - false>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::RIGHT_OUTER_JOIN>, - false>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::CROSS_JOIN>, false>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::RIGHT_SEMI_JOIN>, - false>, - ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::RIGHT_ANTI_JOIN>, - false>, + ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::INNER_JOIN>>, + ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::LEFT_SEMI_JOIN>>, + ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::LEFT_ANTI_JOIN>>, + ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::LEFT_OUTER_JOIN>>, + ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::FULL_OUTER_JOIN>>, + ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::RIGHT_OUTER_JOIN>>, + ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::CROSS_JOIN>>, + ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::RIGHT_SEMI_JOIN>>, + ProcessHashTableProbe<std::integral_constant<TJoinOp::type, TJoinOp::RIGHT_ANTI_JOIN>>, ProcessHashTableProbe< - std::integral_constant<TJoinOp::type, TJoinOp::NULL_AWARE_LEFT_ANTI_JOIN>, false>>; + std::integral_constant<TJoinOp::type, TJoinOp::NULL_AWARE_LEFT_ANTI_JOIN>>>; class HashJoinNode : public ::doris::ExecNode { public: @@ -353,7 +329,6 @@ private: ColumnUInt8::MutablePtr _null_map_column; bool _need_null_map_for_probe = false; bool _has_set_need_null_map_for_probe = false; - bool _need_null_map_for_build = false; bool _has_set_need_null_map_for_build = false; bool _probe_ignore_null = false; int _probe_index = -1; @@ -405,8 +380,9 @@ private: Status _extract_join_column(Block& block, ColumnUInt8::MutablePtr& null_map, ColumnRawPtrs& raw_ptrs, const std::vector<int>& res_col_ids); - template <bool BuildSide> - bool _need_null_map(Block& block, const std::vector<int>& res_col_ids); + bool _need_probe_null_map(Block& block, const std::vector<int>& res_col_ids); + + void _set_build_ignore_flag(Block& block, const std::vector<int>& res_col_ids); void _hash_table_init(); void _process_hashtable_ctx_variants_init(RuntimeState* state); @@ -430,7 +406,7 @@ private: template <class HashTableContext> friend struct ProcessHashTableBuild; - template <class JoinOpType, bool ignore_null> + template <class JoinOpType> friend struct ProcessHashTableProbe; template <class HashTableContext> --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org