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 101628c  [Bug] Fix bug of predicate pushdown logic (#3475)
101628c is described below

commit 101628c81314f1597e1018faa41414b7a19037d8
Author: Mingyu Chen <morningman....@gmail.com>
AuthorDate: Wed May 6 15:15:37 2020 +0800

    [Bug] Fix bug of predicate pushdown logic (#3475)
    
    When there is subquery in where clause, the query will be rewritten to join 
operation.
    And some auxiliary binary predicates will be generated. These binary 
predicates
    will not go through the ExprRewriteRule, so they are not normalized as
    "column to the left and constant to the right" format.
    
    We need to take this case into account so that the `canPushDownPredicate()` 
judgement
    will not throw exception.
---
 .../java/org/apache/doris/analysis/Predicate.java  | 21 ++++++++++-
 .../org/apache/doris/planner/QueryPlanTest.java    | 44 +++++++++++++++++++++-
 2 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/fe/src/main/java/org/apache/doris/analysis/Predicate.java 
b/fe/src/main/java/org/apache/doris/analysis/Predicate.java
index d345cdb..3e2c22b 100644
--- a/fe/src/main/java/org/apache/doris/analysis/Predicate.java
+++ b/fe/src/main/java/org/apache/doris/analysis/Predicate.java
@@ -17,12 +17,13 @@
 
 package org.apache.doris.analysis;
 
-import com.google.common.base.Preconditions;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.Pair;
 import org.apache.doris.common.Reference;
 
+import com.google.common.base.Preconditions;
+
 public abstract class Predicate extends Expr {
     protected boolean isEqJoinConjunct;
 
@@ -109,7 +110,23 @@ public abstract class Predicate extends Expr {
 
                 // because isSingleColumnPredicate
                 Preconditions.checkState(right != null);
-                Preconditions.checkState(right.isConstant());
+
+                // ATTN(cmy): Usually, the BinaryPredicate in the query will 
be rewritten through ExprRewriteRule,
+                // and all SingleColumnPredicate will be rewritten as "column 
on the left and the constant on the right".
+                // So usually the right child is constant.
+                //
+                // But if there is a subquery in where clause, the planner 
will rewrite the subquery to join.
+                // During the rewrite, some auxiliary BinaryPredicate will be 
automatically generated,
+                // and these BinaryPredicates will not go through 
ExprRewriteRule.
+                // As a result, these BinaryPredicates may be as "column on 
the right and the constant on the left".
+                // Example can be found in QueryPlanTest.java -> 
testJoinPredicateTransitivityWithSubqueryInWhereClause().
+                //
+                // Because our current planner implementation is very 
error-prone, so when this happens,
+                // we simply assume that these kind of BinaryPredicates cannot 
be pushed down,
+                // to ensure that this change will not affect other query 
plans.
+                if (!right.isConstant()) {
+                    return false;
+                }
 
                 return right instanceof LiteralExpr;
             }
diff --git a/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java 
b/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java
index 53a3c15..c192d18 100644
--- a/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java
+++ b/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java
@@ -242,6 +242,32 @@ public class QueryPlanTest {
                 "PROPERTIES (\n" +
                 " \"replication_num\" = \"1\"\n" +
                 ");");
+        
+        createTable("CREATE TABLE test.`pushdown_test` (\n" +
+                "  `k1` tinyint(4) NULL COMMENT \"\",\n" + 
+                "  `k2` smallint(6) NULL COMMENT \"\",\n" + 
+                "  `k3` int(11) NULL COMMENT \"\",\n" + 
+                "  `k4` bigint(20) NULL COMMENT \"\",\n" + 
+                "  `k5` decimal(9, 3) NULL COMMENT \"\",\n" + 
+                "  `k6` char(5) NULL COMMENT \"\",\n" + 
+                "  `k10` date NULL COMMENT \"\",\n" + 
+                "  `k11` datetime NULL COMMENT \"\",\n" + 
+                "  `k7` varchar(20) NULL COMMENT \"\",\n" + 
+                "  `k8` double MAX NULL COMMENT \"\",\n" + 
+                "  `k9` float SUM NULL COMMENT \"\"\n" + 
+                ") ENGINE=OLAP\n" + 
+                "AGGREGATE KEY(`k1`, `k2`, `k3`, `k4`, `k5`, `k6`, `k10`, 
`k11`, `k7`)\n" + 
+                "COMMENT \"OLAP\"\n" + 
+                "PARTITION BY RANGE(`k1`)\n" + 
+                "(PARTITION p1 VALUES [(\"-128\"), (\"-64\")),\n" + 
+                "PARTITION p2 VALUES [(\"-64\"), (\"0\")),\n" + 
+                "PARTITION p3 VALUES [(\"0\"), (\"64\")))\n" + 
+                "DISTRIBUTED BY HASH(`k1`) BUCKETS 5\n" + 
+                "PROPERTIES (\n" + 
+                "\"replication_num\" = \"1\",\n" + 
+                "\"in_memory\" = \"false\",\n" + 
+                "\"storage_format\" = \"DEFAULT\"\n" + 
+                ");");
     }
 
     @AfterClass
@@ -532,7 +558,7 @@ public class QueryPlanTest {
     }
 
     @Test
-    public void  testJoinPredicateTransitivity() throws Exception {
+    public void testJoinPredicateTransitivity() throws Exception {
         connectContext.setDatabase("default_cluster:test");
 
         // test left join : left table where binary predicate
@@ -624,10 +650,24 @@ public class QueryPlanTest {
         // test inner join: right table join predicate, both push down left 
table and right table
         sql = "select *\n from join1\n" +
                 "join join2 on join1.id = join2.id\n" +
-                "and join2.id > 1;";
+                "and 1 < join2.id;";
         explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, 
"explain " + sql);
         System.out.println(explainString);
         Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` > 
1"));
         Assert.assertTrue(explainString.contains("PREDICATES: `join2`.`id` > 
1"));
     }
+    
+    @Test
+    public void testJoinPredicateTransitivityWithSubqueryInWhereClause() 
throws Exception {
+        connectContext.setDatabase("default_cluster:test");
+        String sql = "SELECT *\n" + 
+                "FROM test.pushdown_test\n" +
+                "WHERE 0 < (\n" +
+                "    SELECT MAX(k9)\n" + 
+                "    FROM test.pushdown_test);";
+        String explainString = 
UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql);
+        Assert.assertTrue(explainString.contains("PLAN FRAGMENT"));
+        Assert.assertTrue(explainString.contains("CROSS JOIN"));
+        Assert.assertTrue(!explainString.contains("PREDICATES"));
+    }
 }


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

Reply via email to