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]

Reply via email to