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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]