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 2022/10/31 08:21:36 UTC
[doris] branch branch-1.1-lts updated: [cherry-pick](join) fix incorrect result when using anti join with other join predicates (#13812)
This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-1.1-lts
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-1.1-lts by this push:
new a853d69bb1 [cherry-pick](join) fix incorrect result when using anti join with other join predicates (#13812)
a853d69bb1 is described below
commit a853d69bb147ab3d11aa960952c8e63446cc6c55
Author: luozenglin <37...@users.noreply.github.com>
AuthorDate: Mon Oct 31 16:21:29 2022 +0800
[cherry-pick](join) fix incorrect result when using anti join with other join predicates (#13812)
---
.../java/org/apache/doris/analysis/Analyzer.java | 29 +++++++++++++++++++++-
.../apache/doris/planner/SingleNodePlanner.java | 7 +++---
2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java
index 14a357f4b0..c0c71289ea 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java
@@ -264,6 +264,8 @@ public class Analyzer {
// corresponding value could be an empty list. There is no entry for non-outer joins.
public final Map<TupleId, List<ExprId>> conjunctsByOjClause = Maps.newHashMap();
+ public final Map<TupleId, List<ExprId>> conjunctsByAntiJoinClause = Maps.newHashMap();
+
// map from registered conjunct to its containing outer join On clause (represented
// by its right-hand side table ref); only conjuncts that can only be correctly
// evaluated by the originating outer join are registered here
@@ -1262,6 +1264,27 @@ public class Analyzer {
return result;
}
+ /**
+ * Return all unassigned conjuncts of the anti join referenced by
+ * right-hand side table ref.
+ */
+ public List<Expr> getUnassignedAntiJoinConjuncts(TableRef ref) {
+ Preconditions.checkState(ref.getJoinOp().isAntiJoin());
+ List<Expr> result = Lists.newArrayList();
+ List<ExprId> candidates = globalState.conjunctsByAntiJoinClause.get(ref.getId());
+ if (candidates == null) {
+ return result;
+ }
+ for (ExprId conjunctId : candidates) {
+ if (!globalState.assignedConjuncts.contains(conjunctId)) {
+ Expr e = globalState.conjuncts.get(conjunctId);
+ Preconditions.checkState(e != null);
+ result.add(e);
+ }
+ }
+ return result;
+ }
+
/**
* Returns true if 'e' must be evaluated after or by a join node. Note that it may
* still be safe to evaluate 'e' elsewhere as well, but in any case 'e' must be
@@ -1507,6 +1530,10 @@ public class Analyzer {
}
if (rhsRef.getJoinOp().isSemiJoin()) {
globalState.sjClauseByConjunct.put(conjunct.getId(), rhsRef);
+ if (rhsRef.getJoinOp().isAntiJoin()) {
+ globalState.conjunctsByAntiJoinClause.computeIfAbsent(rhsRef.getId(), k -> Lists.newArrayList())
+ .add(conjunct.getId());
+ }
}
if (rhsRef.getJoinOp().isInnerJoin()) {
globalState.ijClauseByConjunct.put(conjunct.getId(), rhsRef);
@@ -1524,7 +1551,7 @@ public class Analyzer {
* Throws an AnalysisException if there is an error evaluating `conjunct`
*/
private void markConstantConjunct(Expr conjunct, boolean fromHavingClause) throws AnalysisException {
- if (!conjunct.isConstant() || isOjConjunct(conjunct)) {
+ if (!conjunct.isConstant() || isOjConjunct(conjunct) || isAntiJoinedConjunct(conjunct)) {
return;
}
if ((!fromHavingClause && !hasEmptySpjResultSet_) || (fromHavingClause && !hasEmptyResultSet_)) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
index b233d9ce9f..30dc5eb27e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
@@ -1858,12 +1858,13 @@ public class SingleNodePlanner {
// Also assign conjuncts from On clause. All remaining unassigned conjuncts
// that can be evaluated by this join are assigned in createSelectPlan().
ojConjuncts = analyzer.getUnassignedOjConjuncts(innerRef);
- analyzer.markConjunctsAssigned(ojConjuncts);
- } else if (innerRef.getJoinOp().isSemiAntiJoin()) {
+ } else if (innerRef.getJoinOp().isAntiJoin()) {
+ ojConjuncts = analyzer.getUnassignedAntiJoinConjuncts(innerRef);
+ } else if (innerRef.getJoinOp().isSemiJoin()) {
final List<TupleId> tupleIds = innerRef.getAllTupleIds();
ojConjuncts = analyzer.getUnassignedConjuncts(tupleIds, false);
- analyzer.markConjunctsAssigned(ojConjuncts);
}
+ analyzer.markConjunctsAssigned(ojConjuncts);
HashJoinNode result =
new HashJoinNode(ctx.getNextNodeId(), outer, inner, innerRef, eqJoinConjuncts,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org