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

yiguolei pushed a commit to branch branch-1.2-lts
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-1.2-lts by this push:
     new b7b3e98df6 [Enhancement](planner)support sql_select_limit for 1.2 
(#21068)
b7b3e98df6 is described below

commit b7b3e98df65ef9ae5008b70b371088e45565f3f6
Author: mch_ucchi <41606806+sohardforan...@users.noreply.github.com>
AuthorDate: Wed Jun 21 22:49:36 2023 +0800

    [Enhancement](planner)support sql_select_limit for 1.2 (#21068)
---
 .../apache/doris/planner/SingleNodePlanner.java    | 43 ++++++++++------
 .../suites/query_p0/test_sql_select_limit.groovy   | 58 ++++++++++++++++++++++
 2 files changed, 85 insertions(+), 16 deletions(-)

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 d30c29f802..1be176bd46 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
@@ -172,8 +172,12 @@ public class SingleNodePlanner {
         if (LOG.isTraceEnabled()) {
             LOG.trace("desctbl: " + analyzer.getDescTbl().debugString());
         }
+        long sqlSelectLimit = -1;
+        if (ConnectContext.get() != null && 
ConnectContext.get().getSessionVariable() != null) {
+            sqlSelectLimit = 
ConnectContext.get().getSessionVariable().sqlSelectLimit;
+        }
         PlanNode singleNodePlan = createQueryPlan(queryStmt, analyzer,
-                ctx.getQueryOptions().getDefaultOrderByLimit());
+                ctx.getQueryOptions().getDefaultOrderByLimit(), 
sqlSelectLimit);
         Preconditions.checkNotNull(singleNodePlan);
         analyzer.getDescTbl().materializeIntermediateSlots();
         return singleNodePlan;
@@ -233,7 +237,7 @@ public class SingleNodePlanner {
      * Create plan tree for single-node execution. Generates PlanNodes for the
      * Select/Project/Join/Union [All]/Group by/Having/Order by clauses of the 
query stmt.
      */
-    private PlanNode createQueryPlan(QueryStmt stmt, Analyzer analyzer, long 
defaultOrderByLimit)
+    private PlanNode createQueryPlan(QueryStmt stmt, Analyzer analyzer, long 
defaultOrderByLimit, long sqlSelectLimit)
             throws UserException {
         long newDefaultOrderByLimit = defaultOrderByLimit;
         long defaultLimit = 
analyzer.getContext().getSessionVariable().defaultOrderByLimit;
@@ -267,7 +271,7 @@ public class SingleNodePlanner {
             }
         } else {
             Preconditions.checkState(stmt instanceof SetOperationStmt);
-            root = createSetOperationPlan((SetOperationStmt) stmt, analyzer, 
newDefaultOrderByLimit);
+            root = createSetOperationPlan((SetOperationStmt) stmt, analyzer, 
newDefaultOrderByLimit, sqlSelectLimit);
         }
 
         // Avoid adding a sort node if the sort tuple has no materialized 
slots.
@@ -295,6 +299,9 @@ public class SingleNodePlanner {
             ((SortNode) root).setDefaultLimit(limit == -1);
             ((SortNode) root).setOffset(stmt.getOffset());
             if (useTopN) {
+                if (sqlSelectLimit > -1) {
+                    newDefaultOrderByLimit = Math.min(newDefaultOrderByLimit, 
sqlSelectLimit);
+                }
                 root.setLimit(limit != -1 ? limit : newDefaultOrderByLimit);
             } else {
                 root.setLimit(limit);
@@ -305,7 +312,11 @@ public class SingleNodePlanner {
             // from SelectStmt outside
             root = addUnassignedConjuncts(analyzer, root);
         } else {
-            root.setLimitAndOffset(stmt.getLimit(), stmt.getOffset());
+            if (!stmt.hasLimit()) {
+                root.setLimitAndOffset(sqlSelectLimit, stmt.getOffset());
+            } else {
+                root.setLimitAndOffset(stmt.getLimit(), stmt.getOffset());
+            }
             root.computeStats(analyzer);
         }
 
@@ -314,7 +325,7 @@ public class SingleNodePlanner {
             root = createAssertRowCountNode(root, 
stmt.getAssertNumRowsElement(), analyzer);
         }
 
-        if (analyzer.hasEmptyResultSet()) {
+        if (analyzer.hasEmptyResultSet() || root.getLimit() == 0 || 
newDefaultOrderByLimit == 0) {
             // Must clear the scanNodes, otherwise we will get NPE in 
Coordinator::computeScanRangeAssignment
             Set<TupleId> scanTupleIds = new 
HashSet<>(root.getAllScanTupleIds());
             scanNodes.removeIf(scanNode -> 
scanTupleIds.contains(scanNode.getTupleIds().get(0)));
@@ -1615,7 +1626,7 @@ public class SingleNodePlanner {
             }
         }
 
-        PlanNode rootNode = createQueryPlan(inlineViewRef.getViewStmt(), 
inlineViewRef.getAnalyzer(), -1);
+        PlanNode rootNode = createQueryPlan(inlineViewRef.getViewStmt(), 
inlineViewRef.getAnalyzer(), -1, -1);
         // TODO: we should compute the "physical layout" of the view's 
descriptor, so that
         // the avg row size is available during optimization; however, that 
means we need to
         // select references to its resultExprs from the enclosing scope(s)
@@ -2187,7 +2198,7 @@ public class SingleNodePlanner {
      */
     private SetOperationNode createSetOperationPlan(
             Analyzer analyzer, SetOperationStmt setOperationStmt, 
List<SetOperationStmt.SetOperand> setOperands,
-            PlanNode result, long defaultOrderByLimit)
+            PlanNode result, long defaultOrderByLimit, long sqlSelectLimit)
             throws UserException, AnalysisException {
         SetOperationNode setOpNode;
         SetOperationStmt.Operation operation = null;
@@ -2246,7 +2257,7 @@ public class SingleNodePlanner {
                     continue;
                 }
             }
-            PlanNode opPlan = createQueryPlan(queryStmt, op.getAnalyzer(), 
defaultOrderByLimit);
+            PlanNode opPlan = createQueryPlan(queryStmt, op.getAnalyzer(), 
defaultOrderByLimit, sqlSelectLimit);
             // There may still be unassigned conjuncts if the operand has an 
order by + limit.
             // Place them into a SelectNode on top of the operand's plan.
             opPlan = addUnassignedConjuncts(analyzer, opPlan.getTupleIds(), 
opPlan);
@@ -2276,7 +2287,7 @@ public class SingleNodePlanner {
      * use a union node (this is tricky because a union materializes a new 
tuple).
      */
     private PlanNode createSetOperationPlan(
-            SetOperationStmt setOperationStmt, Analyzer analyzer, long 
defaultOrderByLimit)
+            SetOperationStmt setOperationStmt, Analyzer analyzer, long 
defaultOrderByLimit, long sqlSelectLimit)
             throws UserException, AnalysisException {
         // TODO(zc): get unassigned conjuncts
         // List<Expr> conjuncts =
@@ -2346,10 +2357,10 @@ public class SingleNodePlanner {
                     if (operation == SetOperationStmt.Operation.INTERSECT
                             || operation == SetOperationStmt.Operation.EXCEPT) 
{
                         result = createSetOperationPlan(analyzer, 
setOperationStmt, partialOperands, result,
-                                defaultOrderByLimit);
+                                defaultOrderByLimit, sqlSelectLimit);
                     } else {
                         result = createUnionPartialSetOperationPlan(analyzer, 
setOperationStmt, partialOperands, result,
-                                defaultOrderByLimit);
+                                defaultOrderByLimit, sqlSelectLimit);
                     }
                     partialOperands.clear();
                 }
@@ -2363,10 +2374,10 @@ public class SingleNodePlanner {
             if (operation == SetOperationStmt.Operation.INTERSECT
                     || operation == SetOperationStmt.Operation.EXCEPT) {
                 result = createSetOperationPlan(analyzer, setOperationStmt, 
partialOperands, result,
-                        defaultOrderByLimit);
+                        defaultOrderByLimit, sqlSelectLimit);
             } else {
                 result = createUnionPartialSetOperationPlan(analyzer, 
setOperationStmt, partialOperands, result,
-                        defaultOrderByLimit);
+                        defaultOrderByLimit, sqlSelectLimit);
             }
         }
 
@@ -2384,7 +2395,7 @@ public class SingleNodePlanner {
     // while the left-hand child(a)'s operation is null
     private PlanNode createUnionPartialSetOperationPlan(Analyzer analyzer, 
SetOperationStmt setOperationStmt,
                                                         
List<SetOperationStmt.SetOperand> setOperands,
-                                                        PlanNode result, long 
defaultOrderByLimit)
+                                                        PlanNode result, long 
defaultOrderByLimit, long sqlSelectLimit)
             throws UserException {
         boolean hasDistinctOps = false;
         boolean hasAllOps = false;
@@ -2403,7 +2414,7 @@ public class SingleNodePlanner {
         // create DISTINCT tree
         if (hasDistinctOps) {
             result = createSetOperationPlan(
-                    analyzer, setOperationStmt, distinctOps, result, 
defaultOrderByLimit);
+                    analyzer, setOperationStmt, distinctOps, result, 
defaultOrderByLimit, sqlSelectLimit);
             result = new AggregationNode(ctx.getNextNodeId(), result,
                     setOperationStmt.getDistinctAggInfo());
             result.init(analyzer);
@@ -2411,7 +2422,7 @@ public class SingleNodePlanner {
         // create ALL tree
         if (hasAllOps) {
             result = createSetOperationPlan(analyzer, setOperationStmt, allOps,
-                    result, defaultOrderByLimit);
+                    result, defaultOrderByLimit, sqlSelectLimit);
         }
         return result;
     }
diff --git a/regression-test/suites/query_p0/test_sql_select_limit.groovy 
b/regression-test/suites/query_p0/test_sql_select_limit.groovy
new file mode 100644
index 0000000000..0d19a7a72a
--- /dev/null
+++ b/regression-test/suites/query_p0/test_sql_select_limit.groovy
@@ -0,0 +1,58 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+suite('sql_select_limit') {
+    sql 'use test_query_db'
+    sql 'set sql_select_limit = 5'
+    sql 'set default_order_by_limit = 4'
+
+    def result = sql "select * from baseall"
+    assertTrue(result.size() == 5)
+
+    result = sql 'select * from baseall order by k1'
+    assertTrue(result.size() == 4)
+
+    result = sql '(select * from baseall) union (select * from test)'
+    assertTrue(result.size() == 5)
+
+    sql 'set sql_select_limit = 4'
+    sql 'set default_order_by_limit = 5'
+
+    result = sql 'select * from baseall'
+    assertTrue(result.size() == 4)
+
+    result = sql 'select * from baseall order by k1'
+    assertTrue(result.size() == 4)
+
+    result = sql '(select * from baseall) union (select * from test)'
+    assertTrue(result.size() == 4)
+
+    sql 'set sql_select_limit = 0'
+
+    result = sql 'select * from baseall'
+    assertTrue(result.size() == 0)
+
+    sql 'set sql_select_limit = -1'
+
+    result = sql 'select * from baseall'
+    assertTrue(result.size() == 16)
+
+    sql 'set sql_select_limit = -10'
+
+    result = sql 'select * from baseall'
+    assertTrue(result.size() == 16)
+}
\ No newline at end of file


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

Reply via email to