You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by yi...@apache.org on 2024/03/07 08:19:59 UTC
(doris) 26/38: [enhancement](nereids) show nullaware semi join in plan (#31738)
This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git
commit 4d259377f31c32aa4c108f6174d26674a8b5ba1f
Author: starocean999 <40...@users.noreply.github.com>
AuthorDate: Thu Mar 7 10:56:54 2024 +0800
[enhancement](nereids) show nullaware semi join in plan (#31738)
---
.../glue/translator/PhysicalPlanTranslator.java | 14 +++++++++++++-
.../java/org/apache/doris/planner/HashJoinNode.java | 19 +++----------------
2 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
index 929bbdb23ca..81ff155f0d7 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
@@ -28,6 +28,7 @@ import org.apache.doris.analysis.FunctionCallExpr;
import org.apache.doris.analysis.GroupByClause.GroupingType;
import org.apache.doris.analysis.GroupingInfo;
import org.apache.doris.analysis.IsNullPredicate;
+import org.apache.doris.analysis.JoinOperator;
import org.apache.doris.analysis.OrderByElement;
import org.apache.doris.analysis.OutFileClause;
import org.apache.doris.analysis.SlotDescriptor;
@@ -1227,6 +1228,7 @@ public class PhysicalPlanTranslator extends DefaultPlanVisitor<PlanFragment, Pla
List<Expr> markConjuncts = ImmutableList.of();
boolean isHashJoinConjunctsEmpty = hashJoin.getHashJoinConjuncts().isEmpty();
boolean isMarkJoinConjunctsEmpty = hashJoin.getMarkJoinConjuncts().isEmpty();
+ JoinOperator joinOperator = JoinType.toJoinOperator(joinType);
if (isHashJoinConjunctsEmpty) {
// if hash join conjuncts is empty, means mark join conjuncts must be EqualPredicate
// BE should use mark join conjuncts to build hash table
@@ -1236,10 +1238,20 @@ public class PhysicalPlanTranslator extends DefaultPlanVisitor<PlanFragment, Pla
.map(e -> JoinUtils.swapEqualToForChildrenOrder(e, hashJoin.left().getOutputSet()))
.map(e -> ExpressionTranslator.translate(e, context))
.collect(Collectors.toList());
+ // in order to process semi/anti join with no hash conjunct and having mark conjunct effeciently
+ // we can use mark conjunct as hash conjunct with slight different behavior if meets null values
+ // so we use null aware semi/anti join to indicate it's a null aware hash conjunct
+ // it's unnecessary to introduce new join type like NULL_AWARE_LEFT_SEMI_JOIN in nereids
+ // so we translate the join type here to let be known if the hash conjunct is null aware
+ if (joinOperator == JoinOperator.LEFT_ANTI_JOIN) {
+ joinOperator = JoinOperator.NULL_AWARE_LEFT_ANTI_JOIN;
+ } else if (joinOperator == JoinOperator.LEFT_SEMI_JOIN) {
+ joinOperator = JoinOperator.NULL_AWARE_LEFT_SEMI_JOIN;
+ }
}
HashJoinNode hashJoinNode = new HashJoinNode(context.nextPlanNodeId(), leftPlanRoot,
- rightPlanRoot, JoinType.toJoinOperator(joinType), execEqConjuncts, Lists.newArrayList(), markConjuncts,
+ rightPlanRoot, joinOperator, execEqConjuncts, Lists.newArrayList(), markConjuncts,
null, null, null, hashJoin.isMarkJoin());
hashJoinNode.setNereidsId(hashJoin.getId());
hashJoinNode.setDistributeExprLists(distributeExprLists);
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 0f099bdca33..1413d42ceee 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
@@ -782,11 +782,8 @@ public class HashJoinNode extends JoinNodeBase {
if (markJoinConjuncts != null) {
if (eqJoinConjuncts.isEmpty()) {
- Preconditions.checkState(joinOp == JoinOperator.LEFT_SEMI_JOIN
- || joinOp == JoinOperator.LEFT_ANTI_JOIN);
- if (joinOp == JoinOperator.LEFT_SEMI_JOIN || joinOp == JoinOperator.LEFT_ANTI_JOIN) {
- msg.hash_join_node.join_op = transformJoinOperator().toThrift();
- }
+ Preconditions.checkState(joinOp == JoinOperator.NULL_AWARE_LEFT_SEMI_JOIN
+ || joinOp == JoinOperator.NULL_AWARE_LEFT_ANTI_JOIN);
// because eqJoinConjuncts mustn't be empty in thrift
// we have to use markJoinConjuncts instead
for (Expr e : markJoinConjuncts) {
@@ -969,19 +966,9 @@ public class HashJoinNode extends JoinNodeBase {
}
}
- private JoinOperator transformJoinOperator() {
- boolean transformToNullAware = markJoinConjuncts != null && eqJoinConjuncts.isEmpty();
- if (joinOp == JoinOperator.LEFT_ANTI_JOIN && transformToNullAware) {
- return JoinOperator.NULL_AWARE_LEFT_ANTI_JOIN;
- } else if (joinOp == JoinOperator.LEFT_SEMI_JOIN && transformToNullAware) {
- return JoinOperator.NULL_AWARE_LEFT_SEMI_JOIN;
- }
- return joinOp;
- }
-
@Override
public boolean isNullAwareLeftAntiJoin() {
- if (transformJoinOperator() == JoinOperator.NULL_AWARE_LEFT_ANTI_JOIN) {
+ if (joinOp == JoinOperator.NULL_AWARE_LEFT_ANTI_JOIN) {
return true;
}
return children.stream().anyMatch(PlanNode::isNullAwareLeftAntiJoin);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org