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

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


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new 9667573506d branch-4.1 [fix](eager-agg) push aggregation down through 
filter (#62669) (#63536)
9667573506d is described below

commit 9667573506d76e70e06e6b7ced07afbde9a95dd7
Author: minghong <[email protected]>
AuthorDate: Thu Jun 4 11:20:12 2026 +0800

    branch-4.1 [fix](eager-agg) push aggregation down through filter (#62669) 
(#63536)
    
    Issue Number: None
    
    Related PR: None
    
    push aggregation down through filter, if filter.child() is not Scan
    
    None
    
    - Test: Manual test
        - Regression test case updated; out refreshed in working tree
    - Behavior changed: Yes (eager agg can safely push through filter while
    preserving filter-required slots)
    - Does this need documentation: No
    
    ### What problem does this PR solve?
    
    Issue Number: close #xxx
    
    Related PR: #xxx
    
    Problem Summary:
    
    ### Release note
    
    None
    
    ### Check List (For Author)
    
    - Test <!-- At least one of them must be included. -->
        - [ ] Regression test
        - [ ] Unit Test
        - [ ] Manual test (add detailed scripts or steps below)
        - [ ] No need to test or manual test. Explain why:
    - [ ] This is a refactor/code format and no logic has been changed.
            - [ ] Previous test can cover this change.
            - [ ] No code files have been changed.
            - [ ] Other reason <!-- Add your reason?  -->
    
    - Behavior changed:
        - [ ] No.
        - [ ] Yes. <!-- Explain the behavior change -->
    
    - Does this need documentation?
        - [ ] No.
    - [ ] Yes. <!-- Add document PR link here. eg:
    https://github.com/apache/doris-website/pull/1214 -->
    
    ### Check List (For Reviewer who merge this PR)
    
    - [ ] Confirm the release note
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label <!-- Add branch pick label that this PR
    should merge into -->
---
 .../eageraggregation/EagerAggRewriterTest.java     | 111 +++++++++++----------
 1 file changed, 56 insertions(+), 55 deletions(-)

diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriterTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriterTest.java
index 397585e530e..799df7838d1 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriterTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriterTest.java
@@ -316,61 +316,6 @@ class EagerAggRewriterTest extends TestWithFeService 
implements MemoPatternMatch
         }
     }
 
-    @Test
-    void testNotPushAggLiteralToNullableSideOfOuterJoin() {
-        // sum(literal), min(literal), max(literal) aggregate over all 
physical rows,
-        // including null-extended rows from the outer join.
-        // Pushing to the nullable side loses the contribution of unmatched 
rows:
-        //   original: sum(2) on unmatched row = 2
-        //   pushed:   sum(NULL) skips the row (wrong!)
-        // So agg(literal) must NOT be pushed to the nullable side.
-        connectContext.getSessionVariable().setEagerAggregationMode(1);
-        connectContext.getSessionVariable().setDisableJoinReorder(true);
-        try {
-            // RIGHT JOIN: t1 is the nullable side (left side of RIGHT JOIN)
-            // sum(2) should NOT be pushed to t1
-            String sql = "select sum(2), t2.id2 from t1 right join t2"
-                    + " on t1.id1 = t2.id2 group by t2.id2";
-            PlanChecker.from(connectContext)
-                    .analyze(sql)
-                    .rewrite()
-                    .nonMatch(logicalJoin(logicalAggregate(), any()))
-                    .printlnTree();
-
-            // LEFT JOIN: t2 is the nullable side (right side of LEFT JOIN)
-            // min(1) should NOT be pushed to t2
-            sql = "select min(1), t1.id1 from t1 left join t2"
-                    + " on t1.id1 = t2.id2 group by t1.id1";
-            PlanChecker.from(connectContext)
-                    .analyze(sql)
-                    .rewrite()
-                    .nonMatch(logicalJoin(any(), logicalAggregate()))
-                    .printlnTree();
-
-            // RIGHT JOIN: max(3) should NOT be pushed to nullable left side
-            sql = "select max(3), t2.id2 from t1 right join t2"
-                    + " on t1.id1 = t2.id2 group by t2.id2";
-            PlanChecker.from(connectContext)
-                    .analyze(sql)
-                    .rewrite()
-                    .nonMatch(logicalJoin(logicalAggregate(), any()))
-                    .printlnTree();
-
-            // Verify agg(nullable_side_col) is still safe to push (no 
regression)
-            // max(t1.name) references the left (nullable) side, so push is 
allowed
-            sql = "select max(t1.name), t2.id2 from t1 right join t2"
-                    + " on t1.id1 = t2.id2 group by t2.id2";
-            PlanChecker.from(connectContext)
-                    .analyze(sql)
-                    .rewrite()
-                    
.matches(logicalAggregate(logicalProject(logicalJoin(logicalAggregate(), 
any()))))
-                    .printlnTree();
-        } finally {
-            connectContext.getSessionVariable().setEagerAggregationMode(0);
-            connectContext.getSessionVariable().setDisableJoinReorder(false);
-        }
-    }
-
     @Test
     void testUniqueFunctionFilterBlocksPushDownThroughFilter() {
         connectContext.getSessionVariable().setEagerAggregationMode(1);
@@ -439,4 +384,60 @@ class EagerAggRewriterTest extends TestWithFeService 
implements MemoPatternMatch
         }
         return null;
     }
+
+    @Test
+    void testNotPushAggLiteralToNullableSideOfOuterJoin() {
+        // sum(literal), min(literal), max(literal) aggregate over all 
physical rows,
+        // including null-extended rows from the outer join.
+        // Pushing to the nullable side loses the contribution of unmatched 
rows:
+        //   original: sum(2) on unmatched row = 2
+        //   pushed:   sum(NULL) skips the row (wrong!)
+        // So agg(literal) must NOT be pushed to the nullable side.
+        connectContext.getSessionVariable().setEagerAggregationMode(1);
+        connectContext.getSessionVariable().setDisableJoinReorder(true);
+        try {
+            // RIGHT JOIN: t1 is the nullable side (left side of RIGHT JOIN)
+            // sum(2) should NOT be pushed to t1
+            String sql = "select sum(2), t2.id2 from t1 right join t2"
+                    + " on t1.id1 = t2.id2 group by t2.id2";
+            PlanChecker.from(connectContext)
+                    .analyze(sql)
+                    .rewrite()
+                    .nonMatch(logicalJoin(logicalAggregate(), any()))
+                    .printlnTree();
+
+            // LEFT JOIN: t2 is the nullable side (right side of LEFT JOIN)
+            // min(1) should NOT be pushed to t2
+            sql = "select min(1), t1.id1 from t1 left join t2"
+                    + " on t1.id1 = t2.id2 group by t1.id1";
+            PlanChecker.from(connectContext)
+                    .analyze(sql)
+                    .rewrite()
+                    .nonMatch(logicalJoin(any(), logicalAggregate()))
+                    .printlnTree();
+
+            // RIGHT JOIN: max(3) should NOT be pushed to nullable left side
+            sql = "select max(3), t2.id2 from t1 right join t2"
+                    + " on t1.id1 = t2.id2 group by t2.id2";
+            PlanChecker.from(connectContext)
+                    .analyze(sql)
+                    .rewrite()
+                    .nonMatch(logicalJoin(logicalAggregate(), any()))
+                    .printlnTree();
+
+            // Verify agg(nullable_side_col) is still safe to push (no 
regression)
+            // max(t1.name) references the left (nullable) side, so push is 
allowed
+            sql = "select max(t1.name), t2.id2 from t1 right join t2"
+                    + " on t1.id1 = t2.id2 group by t2.id2";
+            PlanChecker.from(connectContext)
+                    .analyze(sql)
+                    .rewrite()
+                    
.matches(logicalAggregate(logicalProject(logicalJoin(logicalAggregate(), 
any()))))
+                    .printlnTree();
+        } finally {
+            connectContext.getSessionVariable().setEagerAggregationMode(0);
+            connectContext.getSessionVariable().setDisableJoinReorder(false);
+        }
+    }
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to