You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2021/01/24 02:14:38 UTC

[incubator-doris] branch master updated: [Bug] Fix bug of outer join cause error result. (#5285)

This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 3db08a1  [Bug] Fix bug of outer join cause error result. (#5285)
3db08a1 is described below

commit 3db08a14bfa2d579008fa9123c8c383861ce3f26
Author: HappenLee <ha...@hotmail.com>
AuthorDate: Sun Jan 24 10:14:26 2021 +0800

    [Bug] Fix bug of outer join cause error result. (#5285)
    
    issue: #5284
---
 .../org/apache/doris/planner/HashJoinNode.java     | 30 ++++++++++++++++++++++
 .../org/apache/doris/planner/QueryPlanTest.java    | 21 +++++++++++++++
 2 files changed, 51 insertions(+)

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 f080a83..e847bfe 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
@@ -26,6 +26,7 @@ import org.apache.doris.analysis.SlotDescriptor;
 import org.apache.doris.analysis.SlotId;
 import org.apache.doris.analysis.SlotRef;
 import org.apache.doris.analysis.TableRef;
+import org.apache.doris.analysis.TupleId;
 import org.apache.doris.catalog.ColumnStats;
 import org.apache.doris.common.UserException;
 import org.apache.doris.thrift.TEqJoinCondition;
@@ -41,6 +42,7 @@ import com.google.common.collect.Lists;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -139,6 +141,10 @@ public class HashJoinNode extends PlanNode {
         // Set smap to the combined children's smaps and apply that to all conjuncts_.
         createDefaultSmap(analyzer);
 
+        // outSmap replace in outer join may cause NULL be replace by literal
+        // so need replace the outsmap in nullableTupleID
+        replaceOutputSmapForOuterJoin();
+
         computeStats(analyzer);
         //assignedConjuncts = analyzr.getAssignedConjuncts();
 
@@ -151,6 +157,30 @@ public class HashJoinNode extends PlanNode {
                 Expr.substituteList(otherJoinConjuncts, combinedChildSmap, analyzer, false);
     }
 
+    private void replaceOutputSmapForOuterJoin() {
+        if (joinOp.isOuterJoin()) {
+            List<Expr> lhs = new ArrayList<>();
+            List<Expr> rhs = new ArrayList<>();
+
+            for (int i = 0; i < outputSmap.size(); i++) {
+                Expr expr = outputSmap.getLhs().get(i);
+                boolean isInNullableTuple = false;
+                for (TupleId tupleId : nullableTupleIds) {
+                    if (expr.isBound(tupleId)) {
+                        isInNullableTuple = true;
+                        break;
+                    }
+                }
+
+                if (!isInNullableTuple) {
+                    lhs.add(outputSmap.getLhs().get(i));
+                    rhs.add(outputSmap.getRhs().get(i));
+                }
+            }
+            outputSmap = new ExprSubstitutionMap(lhs, rhs);
+        }
+    }
+
     @Override
     public void computeStats(Analyzer analyzer) {
         super.computeStats(analyzer);
diff --git a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java
index 92e7664..0928908 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java
@@ -1400,6 +1400,27 @@ public class QueryPlanTest {
         explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql);
         Assert.assertTrue(explainString.contains("PREDICATES: `date` IN ('2020-10-30 00:00:00')"));
     }
+
+    @Test
+    public void testOutJoinSmapReplace() throws Exception {
+        connectContext.setDatabase("default_cluster:test");
+        //valid date
+        String sql = "SELECT a.aid, b.bid FROM (SELECT 3 AS aid) a right outer JOIN (SELECT 4 AS bid) b ON (a.aid=b.bid)";
+        String explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql);
+        Assert.assertTrue(explainString.contains("OUTPUT EXPRS:`a`.`aid` | 4"));
+
+        sql = "SELECT a.aid, b.bid FROM (SELECT 3 AS aid) a left outer JOIN (SELECT 4 AS bid) b ON (a.aid=b.bid)";
+        explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql);
+        Assert.assertTrue(explainString.contains("OUTPUT EXPRS:3 | `b`.`bid`"));
+
+        sql = "SELECT a.aid, b.bid FROM (SELECT 3 AS aid) a full outer JOIN (SELECT 4 AS bid) b ON (a.aid=b.bid)";
+        explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql);
+        Assert.assertTrue(explainString.contains("OUTPUT EXPRS:`a`.`aid` | `b`.`bid`"));
+
+        sql = "SELECT a.aid, b.bid FROM (SELECT 3 AS aid) a JOIN (SELECT 4 AS bid) b ON (a.aid=b.bid)";
+        explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql);
+        Assert.assertTrue(explainString.contains("OUTPUT EXPRS:3 | 4"));
+    }
 }
 
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org