This is an automated email from the ASF dual-hosted git repository. starocean999 pushed a commit to branch branch-2.0 in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.0 by this push: new 0cf27ad29bd [fix](nereids)NullSafeEqualToEqual rule only change to equal if both children are not nullable (#32374) (#32771) 0cf27ad29bd is described below commit 0cf27ad29bdcd9461559c592fd75e36f87c127b7 Author: Jerry Hu <mrh...@gmail.com> AuthorDate: Mon Mar 25 17:50:22 2024 +0800 [fix](nereids)NullSafeEqualToEqual rule only change to equal if both children are not nullable (#32374) (#32771) Co-authored-by: starocean999 <40539150+starocean...@users.noreply.github.com> --- be/src/vec/exec/join/vhash_join_node.cpp | 42 +++++++++++++--------- be/src/vec/exec/join/vhash_join_node.h | 4 ++- .../org/apache/doris/planner/HashJoinNode.java | 2 +- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/be/src/vec/exec/join/vhash_join_node.cpp b/be/src/vec/exec/join/vhash_join_node.cpp index 7990f5bd274..8b52608433c 100644 --- a/be/src/vec/exec/join/vhash_join_node.cpp +++ b/be/src/vec/exec/join/vhash_join_node.cpp @@ -362,13 +362,23 @@ Status HashJoinNode::init(const TPlanNode& tnode, RuntimeState* state) { eq_join_conjunct.opcode == TExprOpcode::EQ_FOR_NULL; _is_null_safe_eq_join.push_back(null_aware); + const bool build_side_nullable = _build_expr_ctxs.back()->root()->is_nullable(); + const bool probe_side_nullable = _probe_expr_ctxs.back()->root()->is_nullable(); // if is null aware, build join column and probe join column both need dispose null value - _store_null_in_hash_table.emplace_back( - null_aware || - (_build_expr_ctxs.back()->root()->is_nullable() && build_stores_null)); + _store_null_in_hash_table.emplace_back(null_aware || + (build_side_nullable && build_stores_null)); probe_not_ignore_null[conjuncts_index] = - null_aware || - (_probe_expr_ctxs.back()->root()->is_nullable() && probe_dispose_null); + null_aware || (probe_side_nullable && probe_dispose_null); + + const bool should_convert_build_side_to_nullable = + null_aware && !build_side_nullable && probe_side_nullable; + const bool should_convert_probe_side_to_nullable = + (null_aware || _join_op == TJoinOp::RIGHT_ANTI_JOIN) && build_side_nullable && + !probe_side_nullable; + + _should_convert_build_side_to_nullable.emplace_back(should_convert_build_side_to_nullable); + _should_convert_probe_side_to_nullable.emplace_back(should_convert_probe_side_to_nullable); + conjuncts_index++; } for (size_t i = 0; i < _probe_expr_ctxs.size(); ++i) { @@ -838,7 +848,7 @@ void HashJoinNode::_prepare_probe_block() { column_type.column = remove_nullable(column_type.column); column_type.type = remove_nullable(column_type.type); } - _temp_probe_nullable_columns.clear(); + _key_columns_holder.clear(); release_block_memory(_probe_block); } @@ -1060,8 +1070,17 @@ Status HashJoinNode::_extract_join_column(Block& block, ColumnUInt8::MutablePtr& ColumnRawPtrs& raw_ptrs, const std::vector<int>& res_col_ids) { DCHECK_EQ(_build_expr_ctxs.size(), _probe_expr_ctxs.size()); - _temp_probe_nullable_columns.clear(); + _key_columns_holder.clear(); + auto& should_convert_to_nullable = BuildSide ? _should_convert_build_side_to_nullable + : _should_convert_probe_side_to_nullable; for (size_t i = 0; i < _build_expr_ctxs.size(); ++i) { + if (should_convert_to_nullable[i]) { + _key_columns_holder.emplace_back( + make_nullable(block.get_by_position(res_col_ids[i]).column)); + raw_ptrs[i] = _key_columns_holder.back().get(); + continue; + } + if (_is_null_safe_eq_join[i]) { raw_ptrs[i] = block.get_by_position(res_col_ids[i]).column.get(); } else { @@ -1084,15 +1103,6 @@ Status HashJoinNode::_extract_join_column(Block& block, ColumnUInt8::MutablePtr& raw_ptrs[i] = &col_nested; } } else { - if constexpr (!BuildSide) { - if (_join_op == TJoinOp::RIGHT_ANTI_JOIN && - _build_expr_ctxs[i]->root()->is_nullable()) { - _temp_probe_nullable_columns.emplace_back(make_nullable( - block.get_by_position(res_col_ids[i]).column->assume_mutable())); - raw_ptrs[i] = _temp_probe_nullable_columns.back().get(); - continue; - } - } raw_ptrs[i] = column; } } diff --git a/be/src/vec/exec/join/vhash_join_node.h b/be/src/vec/exec/join/vhash_join_node.h index e5f539967cb..80085d898e0 100644 --- a/be/src/vec/exec/join/vhash_join_node.h +++ b/be/src/vec/exec/join/vhash_join_node.h @@ -293,9 +293,11 @@ private: // mark the build hash table whether it needs to store null value std::vector<bool> _store_null_in_hash_table; + std::vector<bool> _should_convert_build_side_to_nullable; + std::vector<bool> _should_convert_probe_side_to_nullable; // In right anti join, if the probe side is not nullable and the build side is nullable, // we need to convert the probe column to nullable. - std::vector<ColumnPtr> _temp_probe_nullable_columns; + std::vector<vectorized::ColumnPtr> _key_columns_holder; std::vector<uint16_t> _probe_column_disguise_null; std::vector<uint16_t> _probe_column_convert_to_null; diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/HashJoinNode.java b/fe/fe-core/src/main/java/org/apache/doris/planner/HashJoinNode.java index 1e267319c7f..150adfd540d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/HashJoinNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/HashJoinNode.java @@ -144,7 +144,7 @@ public class HashJoinNode extends JoinNodeBase { BinaryPredicate eqJoin = (BinaryPredicate) eqJoinPredicate; if (eqJoin.getOp().equals(BinaryPredicate.Operator.EQ_FOR_NULL)) { Preconditions.checkArgument(eqJoin.getChildren().size() == 2); - if (!eqJoin.getChild(0).isNullable() || !eqJoin.getChild(1).isNullable()) { + if (!eqJoin.getChild(0).isNullable() && !eqJoin.getChild(1).isNullable()) { eqJoin.setOp(BinaryPredicate.Operator.EQ); } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org