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