You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by ka...@apache.org on 2020/08/10 02:30:11 UTC

[incubator-doris] branch master updated: Fix window function with limit zero bug 2 (#4235)

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

kangkaisen 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 f516172  Fix window function with limit zero bug 2 (#4235)
f516172 is described below

commit f516172f2303168e4e26d6ae25f4e0289c830010
Author: kangkaisen <ka...@apache.org>
AuthorDate: Mon Aug 10 10:29:05 2020 +0800

    Fix window function with limit zero bug 2 (#4235)
---
 .../java/org/apache/doris/analysis/SelectStmt.java |  8 +++++
 .../apache/doris/planner/SingleNodePlanner.java    | 38 +++++++++-------------
 .../org/apache/doris/planner/QueryPlanTest.java    | 28 ++++++++++++++++
 3 files changed, 52 insertions(+), 22 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
index f2b057a..405490c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
@@ -1567,6 +1567,13 @@ public class SelectStmt extends QueryStmt {
         return strBuilder.toString();
     }
 
+    /**
+     * If the select statement has a sort/top that is evaluated, then the sort tuple
+     * is materialized. Else, if there is aggregation then the aggregate tuple id is
+     * materialized. Otherwise, all referenced tables are materialized as long as they are
+     * not semi-joined. If there are analytics and no sort, then the returned tuple
+     * ids also include the logical analytic output tuple.
+     */
     @Override
     public void getMaterializedTupleIds(ArrayList<TupleId> tupleIdList) {
         // If select statement has an aggregate, then the aggregate tuple id is materialized.
@@ -1585,6 +1592,7 @@ public class SelectStmt extends QueryStmt {
                 tupleIdList.addAll(tblRef.getMaterializedTupleIds());
             }
         }
+        // Fixme(kks): get tuple id from analyticInfo is wrong, should get from AnalyticEvalNode
         // We materialize the agg tuple or the table refs together with the analytic tuple.
         if (hasAnalyticInfo() && isEvaluateOrderBy()) {
             tupleIdList.add(analyticInfo.getOutputTupleId());
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 1a569a5..d67616a 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
@@ -208,27 +208,6 @@ public class SingleNodePlanner {
      */
     private PlanNode createQueryPlan(QueryStmt stmt, Analyzer analyzer, long defaultOrderByLimit)
             throws UserException {
-        if (analyzer.hasEmptyResultSet()) {
-            PlanNode node = createEmptyNode(stmt, analyzer);
-
-            // handle window function with limit zero
-            if (stmt instanceof SelectStmt) {
-                SelectStmt selectStmt = (SelectStmt) stmt;
-                if (selectStmt.getAnalyticInfo() != null) {
-                    AnalyticInfo analyticInfo = selectStmt.getAnalyticInfo();
-                    AnalyticPlanner analyticPlanner = new AnalyticPlanner(analyticInfo, analyzer, ctx_);
-                    List<Expr> inputPartitionExprs = Lists.newArrayList();
-                    AggregateInfo aggInfo = selectStmt.getAggInfo();
-                    PlanNode root = analyticPlanner.createSingleNodePlan(node,
-                            aggInfo != null ? aggInfo.getGroupingExprs() : null, inputPartitionExprs);
-
-                    // In order to substitute the analytic expr with slot in result exprs
-                    node.setOutputSmap(root.outputSmap);
-                }
-            }
-            return node;
-        }
-
         long newDefaultOrderByLimit = defaultOrderByLimit;
         if (newDefaultOrderByLimit == -1) {
             newDefaultOrderByLimit = 65535;
@@ -300,6 +279,21 @@ public class SingleNodePlanner {
         if (stmt.getAssertNumRowsElement() != null) {
             root = createAssertRowCountNode(root, stmt.getAssertNumRowsElement(), analyzer);
         }
+
+        if (analyzer.hasEmptyResultSet()) {
+            // Must clear the scanNodes, otherwise we will get NPE in Coordinator::computeScanRangeAssignment
+            scanNodes.clear();
+            PlanNode node = createEmptyNode(stmt, analyzer);
+            // Ensure result exprs will be substituted by right outputSmap
+            node.setOutputSmap(root.outputSmap);
+            // Currently, getMaterializedTupleIds for AnalyticEvalNode is wrong,
+            // So we explicitly add AnalyticEvalNode tuple ids to EmptySetNode
+            if (root instanceof AnalyticEvalNode) {
+                node.getTupleIds().addAll(root.tupleIds);
+            }
+            return node;
+        }
+
         return root;
     }
 
@@ -687,7 +681,7 @@ public class SingleNodePlanner {
             rowTuples.addAll(tblRef.getMaterializedTupleIds());
         }
 
-        if (analyzer.hasEmptySpjResultSet()) {
+        if (analyzer.hasEmptySpjResultSet() && selectStmt.getAggInfo() != null) {
             final PlanNode emptySetNode = new EmptySetNode(ctx_.getNextNodeId(), rowTuples);
             emptySetNode.init(analyzer);
             emptySetNode.setOutputSmap(selectStmt.getBaseTblSmap());
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 b9eb997..ff2bc62 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
@@ -17,6 +17,7 @@
 
 package org.apache.doris.planner;
 
+import com.google.common.collect.Lists;
 import org.apache.doris.analysis.CreateDbStmt;
 import org.apache.doris.analysis.CreateTableStmt;
 import org.apache.doris.analysis.DropDbStmt;
@@ -969,4 +970,31 @@ public class QueryPlanTest {
         explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, queryStr);
         Assert.assertTrue(explainString.contains("INNER JOIN (BROADCAST)"));
     }
+
+    @Test
+    public void testEmptyNode() throws Exception {
+        connectContext.setDatabase("default_cluster:test");
+        String emptyNode = "EMPTYSET";
+        String denseRank = "dense_rank";
+
+        List<String> sqls = Lists.newArrayList();
+        sqls.add("explain select * from baseall limit 0");
+        sqls.add("explain select count(*) from baseall limit 0;");
+        sqls.add("explain select k3, dense_rank() OVER () AS rank FROM baseall limit 0;");
+        sqls.add("explain select rank from (select k3, dense_rank() OVER () AS rank FROM baseall) a limit 0;");
+        sqls.add("explain select * from baseall join bigtable as b limit 0");
+
+        sqls.add("explain select * from baseall where 1 = 2");
+        sqls.add("explain select count(*) from baseall where 1 = 2;");
+        sqls.add("explain select k3, dense_rank() OVER () AS rank FROM baseall where 1 =2;");
+        sqls.add("explain select rank from (select k3, dense_rank() OVER () AS rank FROM baseall) a where 1 =2;");
+        sqls.add("explain select * from baseall join bigtable as b where 1 = 2");
+
+        for(String sql: sqls) {
+            String explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, sql);
+            System.out.println(explainString);
+            Assert.assertTrue(explainString.contains(emptyNode));
+            Assert.assertFalse(explainString.contains(denseRank));
+        }
+    }
 }


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