This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.1 by this push:
new b22078d0c07 branch-3.1: [enhance](nereids)rewrite aggregate to limit
when all group by key is uniform and not null, and there is no aggregate
functions #46223 (#52091)
b22078d0c07 is described below
commit b22078d0c077ab795c222fa83f5d9e052d63f478
Author: feiniaofeiafei <[email protected]>
AuthorDate: Tue Jul 22 14:07:28 2025 +0800
branch-3.1: [enhance](nereids)rewrite aggregate to limit when all group by
key is uniform and not null, and there is no aggregate functions #46223
(#52091)
cherry-pick from #46223
---
.../rules/rewrite/EliminateGroupByKeyByUniform.java | 10 ++++++++++
.../rules/analysis/NormalizeAggregateTest.java | 5 ++---
.../rewrite/EliminateGroupByKeyByUniformTest.java | 8 +++-----
.../eliminate_group_by_key_by_uniform.out | Bin 3536 -> 4819 bytes
.../eliminate_group_by_key_by_uniform.groovy | 15 +++++++++++++++
.../suites/trino_p0/constant_group_key.groovy | 2 +-
6 files changed, 31 insertions(+), 9 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateGroupByKeyByUniform.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateGroupByKeyByUniform.java
index 4cb39c2a934..d5b33dc5488 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateGroupByKeyByUniform.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateGroupByKeyByUniform.java
@@ -27,10 +27,14 @@ import
org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import
org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction;
import org.apache.doris.nereids.trees.expressions.functions.agg.AnyValue;
+import org.apache.doris.nereids.trees.plans.LimitPhase;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
+import org.apache.doris.nereids.trees.plans.logical.LogicalLimit;
+import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
import org.apache.doris.nereids.trees.plans.visitor.CustomRewriter;
import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanRewriter;
+import org.apache.doris.nereids.util.Utils;
import java.util.ArrayList;
import java.util.HashMap;
@@ -99,6 +103,12 @@ public class EliminateGroupByKeyByUniform extends
DefaultPlanRewriter<Map<ExprId
if (removedExpression.isEmpty()) {
return aggregate;
}
+ /* select 1 c1 from test group by c; -> select 1 c1 from test limit 1
*/
+ if (newGroupBy.isEmpty() &&
aggregate.getAggregateFunctions().isEmpty()) {
+ LogicalProject<Plan> newProject = new LogicalProject<>(
+ Utils.fastToImmutableList(aggregate.getOutput()),
aggregate.child());
+ return new LogicalLimit<Plan>(1, 0, LimitPhase.GLOBAL, newProject);
+ }
// when newGroupBy is empty, need retain one expr in group by,
otherwise the result may be wrong in empty table
if (newGroupBy.isEmpty()) {
Expression expr = removedExpression.iterator().next();
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/NormalizeAggregateTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/NormalizeAggregateTest.java
index 2451bd3c46f..6a66c09b445 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/NormalizeAggregateTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/NormalizeAggregateTest.java
@@ -236,7 +236,7 @@ public class NormalizeAggregateTest extends
TestWithFeService implements MemoPat
PlanChecker.from(connectContext)
.analyze(sql)
.rewrite()
- .matches(logicalAggregate().when(aggregate ->
aggregate.getGroupByExpressions().size() == 1));
+ .nonMatch(logicalAggregate());
}
@Test
@@ -265,8 +265,7 @@ public class NormalizeAggregateTest extends
TestWithFeService implements MemoPat
PlanChecker.from(connectContext)
.analyze(sql)
.rewrite()
- .matches(logicalAggregate()
- .when(agg -> agg.getGroupByExpressions().size() == 1));
+ .nonMatch(logicalAggregate());
}
@Test
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/EliminateGroupByKeyByUniformTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/EliminateGroupByKeyByUniformTest.java
index 78d8034e3fd..6e6df0909ad 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/EliminateGroupByKeyByUniformTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/EliminateGroupByKeyByUniformTest.java
@@ -108,9 +108,7 @@ public class EliminateGroupByKeyByUniformTest extends
TestWithFeService implemen
.analyze("select c2 from (select a c1,1 c2, 3 c3 from
eli_gbk_by_uniform_t) t group by c2,c3 order by 1;")
.rewrite()
.printlnTree()
- .matches(logicalAggregate().when(agg ->
- agg.getGroupByExpressions().size() == 1
- &&
agg.getGroupByExpressions().get(0).toSql().equals("c2")));
+ .nonMatch(logicalAggregate());
}
@Test
@@ -191,7 +189,7 @@ public class EliminateGroupByKeyByUniformTest extends
TestWithFeService implemen
.analyze("select t1.b from eli_gbk_by_uniform_t t1 left semi
join eli_gbk_by_uniform_t t2 on t1.b=t2.b and t2.b=100 group by t1.b")
.rewrite()
.printlnTree()
- .matches(logicalAggregate().when(agg ->
agg.getGroupByExpressions().size() == 1));
+ .nonMatch(logicalAggregate());
}
@Test
@@ -209,7 +207,7 @@ public class EliminateGroupByKeyByUniformTest extends
TestWithFeService implemen
.analyze("select t2.b from eli_gbk_by_uniform_t t1 right semi
join eli_gbk_by_uniform_t t2 on t1.b=t2.b and t2.b=100 group by t2.b")
.rewrite()
.printlnTree()
- .matches(logicalAggregate().when(agg ->
agg.getGroupByExpressions().size() == 1));
+ .nonMatch(logicalAggregate());
}
@Test
diff --git
a/regression-test/data/nereids_rules_p0/eliminate_gby_key/eliminate_group_by_key_by_uniform.out
b/regression-test/data/nereids_rules_p0/eliminate_gby_key/eliminate_group_by_key_by_uniform.out
index f8523c29f3d..14be541c3d5 100644
Binary files
a/regression-test/data/nereids_rules_p0/eliminate_gby_key/eliminate_group_by_key_by_uniform.out
and
b/regression-test/data/nereids_rules_p0/eliminate_gby_key/eliminate_group_by_key_by_uniform.out
differ
diff --git
a/regression-test/suites/nereids_rules_p0/eliminate_gby_key/eliminate_group_by_key_by_uniform.groovy
b/regression-test/suites/nereids_rules_p0/eliminate_gby_key/eliminate_group_by_key_by_uniform.groovy
index 715aa7fe849..1d4bedc0a5c 100644
---
a/regression-test/suites/nereids_rules_p0/eliminate_gby_key/eliminate_group_by_key_by_uniform.groovy
+++
b/regression-test/suites/nereids_rules_p0/eliminate_gby_key/eliminate_group_by_key_by_uniform.groovy
@@ -16,6 +16,7 @@
// under the License.
suite("eliminate_group_by_key_by_uniform") {
sql "set enable_nereids_rules = 'ELIMINATE_GROUP_BY_KEY_BY_UNIFORM'"
+ sql "set runtime_filter_mode=OFF"
sql "drop table if exists eli_gbk_by_uniform_t"
sql """create table eli_gbk_by_uniform_t(a int null, b int not null, c
varchar(10) null, d date, dt datetime)
distributed by hash(a) properties("replication_num"="1");
@@ -221,4 +222,18 @@ suite("eliminate_group_by_key_by_uniform") {
//grouping
qt_grouping "select k, k3 from (select 1 as k, a k3, sum(b) as sum_k1 from
test1 group by cube(k,a)) t group by k,k3 order by 1,2"
+
+ // test agg to limit
+ qt_to_limit_project_uniform "select 1 as c1 from eli_gbk_by_uniform_t
group by c1"
+ qt_to_limit_predicate_uniform "select a from eli_gbk_by_uniform_t where
a=1 group by a"
+ qt_to_limit_project_uniform_has_upper_ref "select c1+1 from (select 1 as
c1 from eli_gbk_by_uniform_t group by c1) t"
+ qt_to_limit_predicate_uniform_has_upper_ref "select a+1 from (select a
from eli_gbk_by_uniform_t where a=1 group by a) t"
+ qt_to_limit_join_predicate "select t2.b from test1 t1 inner join (select *
from test2 where b=105) t2 on t1.a=t2.a group by t2.b order by 1;"
+ qt_to_limit_join_project "select 1 as c1 from test1 t1 inner join (select
* from test2 where b=105) t2 on t1.a=t2.a group by c1 order by 1;"
+ qt_to_limit_multi_group_by "select 1 as c1,a from eli_gbk_by_uniform_t
where a=1 group by c1,a"
+ qt_to_limit_multi_group_by_one_col_in_project "select 2 as c1 from
eli_gbk_by_uniform_t where a=1 group by c1,a"
+
+ qt_to_limit_join_project_shape "explain shape plan select 1 as c1 from
test1 t1 inner join (select * from test2 where b=105) t2 on t1.a=t2.a group by
c1 order by 1;"
+ qt_to_limit_project_uniform_shape "explain shape plan select 1 as c1 from
eli_gbk_by_uniform_t group by c1"
+ qt_to_limit_multi_group_by_shape "explain shape plan select 2 as c1 from
eli_gbk_by_uniform_t where a=1 group by c1,a"
}
\ No newline at end of file
diff --git a/regression-test/suites/trino_p0/constant_group_key.groovy
b/regression-test/suites/trino_p0/constant_group_key.groovy
index 1d9e55a9e11..a0f3cea04b5 100644
--- a/regression-test/suites/trino_p0/constant_group_key.groovy
+++ b/regression-test/suites/trino_p0/constant_group_key.groovy
@@ -26,7 +26,7 @@ suite("constant_group_key") {
//reserve constant key in group by
explain {
sql("select 'oneline' from nation group by 'constant1'")
- contains "group by: 1"
+ contains "limit: 1"
}
explain {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]