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 b6d314c2bb3 branch-4.1 [fix](eager-agg) push aggregation down through 
filter (#62669) (#63915)
b6d314c2bb3 is described below

commit b6d314c2bb35d290060ea3b444abf88f4f60590e
Author: minghong <[email protected]>
AuthorDate: Wed Jun 3 18:41:53 2026 +0800

    branch-4.1 [fix](eager-agg) push aggregation down through filter (#62669) 
(#63915)
    
    pick #62669
    
    ### 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 -->
---
 .../rewrite/eageraggregation/EagerAggRewriter.java |  70 ++++++----
 .../eageraggregation/EagerAggRewriterTest.java     | 128 +++++++++++++++++
 .../data/nereids_p0/eager_agg/eager_agg.out        |  73 ++++++++++
 .../suites/nereids_p0/eager_agg/eager_agg.groovy   | 152 +++++++++++++++++++++
 4 files changed, 398 insertions(+), 25 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriter.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriter.java
index 87050b5bbdf..217854d6033 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriter.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/eageraggregation/EagerAggRewriter.java
@@ -28,7 +28,6 @@ import 
org.apache.doris.nereids.trees.expressions.NamedExpression;
 import org.apache.doris.nereids.trees.expressions.Slot;
 import org.apache.doris.nereids.trees.expressions.SlotReference;
 import 
org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction;
-import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.If;
 import org.apache.doris.nereids.trees.plans.JoinType;
 import org.apache.doris.nereids.trees.plans.Plan;
@@ -54,6 +53,7 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * eager aggregation
@@ -133,34 +133,32 @@ public class EagerAggRewriter extends 
DefaultPlanRewriter<PushDownAggContext> {
             }
         }
 
-        // Do not push count(*)/count(literal)/count(preserved_side_col) to 
the nullable side of outer joins.
-        // count(*) counts all physical rows, including null-extended rows 
from the outer join.
-        // After pushdown to the nullable side, unmatched rows produce NULL 
for the pre-aggregated count,
-        // and ifnull(sum(NULL), 0) = 0, which loses the count of unmatched 
rows.
-        // However, count(nullable_side_col) is safe to push down because for 
unmatched rows,
-        // nullable_side_col IS NULL, so the original count is 0, matching 
ifnull(sum(NULL), 0) = 0.
+        // Do not push agg(literal) or agg(preserved_side_col) to the nullable 
side of outer joins.
+        // Aggregates like count(*), sum(2), min(1) etc. aggregate over all 
physical rows,
+        // including null-extended rows from the outer join.
+        // After pushdown to the nullable side, unmatched rows produce NULL 
for the pre-aggregated value,
+        // losing the contribution of those rows (e.g. sum(2) should add 2 per 
unmatched row,
+        // but sum(NULL) skips them).
+        // However, agg(nullable_side_col) is safe to push down because for 
unmatched rows,
+        // nullable_side_col IS NULL, and the aggregate naturally handles NULL 
values correctly.
         if (!join.getJoinType().isInnerJoin() && 
!join.getJoinType().isCrossJoin()) {
             JoinType joinType = join.getJoinType();
+            boolean leftIsNullable = joinType.isRightOuterJoin() || 
joinType.isFullOuterJoin();
+            boolean rightIsNullable = joinType.isLeftOuterJoin() || 
joinType.isFullOuterJoin();
             for (AggregateFunction aggFunc : context.getAggFunctions()) {
-                if (aggFunc instanceof Count) {
-                    Set<Slot> countInputSlots = aggFunc.getInputSlots();
-                    // Determine which side is nullable
-                    boolean leftIsNullable = joinType.isRightOuterJoin() || 
joinType.isFullOuterJoin();
-                    boolean rightIsNullable = joinType.isLeftOuterJoin() || 
joinType.isFullOuterJoin();
-                    // Check if we're pushing to a nullable side without 
referencing its columns
-                    if (toLeft && leftIsNullable) {
-                        boolean hasLeftInput = countInputSlots.stream()
-                                .anyMatch(slot -> 
join.left().getOutputSet().contains(slot));
-                        if (!hasLeftInput) {
-                            toLeft = false;
-                        }
+                Set<Slot> inputSlots = aggFunc.getInputSlots();
+                if (toLeft && leftIsNullable) {
+                    boolean hasLeftInput = inputSlots.stream()
+                            .anyMatch(slot -> 
join.left().getOutputSet().contains(slot));
+                    if (!hasLeftInput) {
+                        toLeft = false;
                     }
-                    if (toRight && rightIsNullable) {
-                        boolean hasRightInput = countInputSlots.stream()
-                                .anyMatch(slot -> 
join.right().getOutputSet().contains(slot));
-                        if (!hasRightInput) {
-                            toRight = false;
-                        }
+                }
+                if (toRight && rightIsNullable) {
+                    boolean hasRightInput = inputSlots.stream()
+                            .anyMatch(slot -> 
join.right().getOutputSet().contains(slot));
+                    if (!hasRightInput) {
+                        toRight = false;
                     }
                 }
             }
@@ -505,6 +503,28 @@ public class EagerAggRewriter extends 
DefaultPlanRewriter<PushDownAggContext> {
 
     @Override
     public Plan visitLogicalFilter(LogicalFilter<? extends Plan> filter, 
PushDownAggContext context) {
+        if (filter.child() instanceof LogicalRelation) {
+            return genAggregate(filter, context);
+        }
+        if 
(filter.getConjuncts().stream().anyMatch(Expression::containsUniqueFunction)) {
+            return genAggregate(filter, context);
+        }
+        List<SlotReference> filterInputSlots = filter.getInputSlots().stream()
+                .map(slot -> (SlotReference) slot)
+                .collect(Collectors.toList());
+        List<SlotReference> childGroupKeys = Stream.concat(
+                        context.getGroupKeys().stream(),
+                        filterInputSlots.stream())
+                .distinct()
+                .collect(Collectors.toList());
+        PushDownAggContext childContext = 
context.withGroupKeys(childGroupKeys);
+        if (!childContext.isValid()) {
+            return genAggregate(filter, context);
+        }
+        Plan newChild = filter.child().accept(this, childContext);
+        if (newChild != filter.child()) {
+            return filter.withChildren(newChild);
+        }
         return genAggregate(filter, context);
     }
 
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 4b0561ccd0f..397585e530e 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
@@ -17,10 +17,14 @@
 
 package org.apache.doris.nereids.rules.rewrite.eageraggregation;
 
+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.LogicalFilter;
 import org.apache.doris.nereids.util.MemoPatternMatchSupported;
 import org.apache.doris.nereids.util.PlanChecker;
 import org.apache.doris.utframe.TestWithFeService;
 
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
 class EagerAggRewriterTest extends TestWithFeService implements 
MemoPatternMatchSupported {
@@ -311,4 +315,128 @@ class EagerAggRewriterTest extends TestWithFeService 
implements MemoPatternMatch
             connectContext.getSessionVariable().setDisableJoinReorder(false);
         }
     }
+
+    @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);
+        connectContext.getSessionVariable().setDisableJoinReorder(true);
+        try {
+            String sql = "select count(s.name1), t2.id2"
+                    + " from (select * from (select id1, name as name1 from 
t1) s1 where random() < 0.5) s"
+                    + " join t2 on s.id1 = t2.id2 group by t2.id2";
+            Plan plan = PlanChecker.from(connectContext)
+                    .analyze(sql)
+                    .rewrite()
+                    .getPlan();
+            Assertions.assertEquals(2, countPlans(plan, 
LogicalAggregate.class), plan.treeString());
+            LogicalFilter<?> filter = findFirstPlan(plan, LogicalFilter.class);
+            Assertions.assertNotNull(filter, plan.treeString());
+            Assertions.assertFalse(containsPlan(filter.child(), 
LogicalAggregate.class), plan.treeString());
+        } finally {
+            connectContext.getSessionVariable().setEagerAggregationMode(0);
+            connectContext.getSessionVariable().setDisableJoinReorder(false);
+        }
+    }
+
+    @Test
+    void testInvalidFilterContextFallsBackToCurrentFilter() {
+        connectContext.getSessionVariable().setEagerAggregationMode(1);
+        connectContext.getSessionVariable().setDisableJoinReorder(true);
+        try {
+            String sql = "select count(s.name1), t2.id2"
+                    + " from (select * from (select id1, name as name1 from 
t1) s1 where s1.name1 is not null) s"
+                    + " join t2 on s.id1 = t2.id2 group by t2.id2";
+            Plan plan = PlanChecker.from(connectContext)
+                    .analyze(sql)
+                    .rewrite()
+                    .getPlan();
+            Assertions.assertEquals(2, countPlans(plan, 
LogicalAggregate.class), plan.treeString());
+            LogicalFilter<?> filter = findFirstPlan(plan, LogicalFilter.class);
+            Assertions.assertNotNull(filter, plan.treeString());
+            Assertions.assertFalse(containsPlan(filter.child(), 
LogicalAggregate.class), plan.treeString());
+        } finally {
+            connectContext.getSessionVariable().setEagerAggregationMode(0);
+            connectContext.getSessionVariable().setDisableJoinReorder(false);
+        }
+    }
+
+    private int countPlans(Plan plan, Class<? extends Plan> clazz) {
+        int count = clazz.isInstance(plan) ? 1 : 0;
+        for (Plan child : plan.children()) {
+            count += countPlans(child, clazz);
+        }
+        return count;
+    }
+
+    private boolean containsPlan(Plan plan, Class<? extends Plan> clazz) {
+        return countPlans(plan, clazz) > 0;
+    }
+
+    private <T extends Plan> T findFirstPlan(Plan plan, Class<T> clazz) {
+        if (clazz.isInstance(plan)) {
+            return clazz.cast(plan);
+        }
+        for (Plan child : plan.children()) {
+            T matched = findFirstPlan(child, clazz);
+            if (matched != null) {
+                return matched;
+            }
+        }
+        return null;
+    }
 }
diff --git a/regression-test/data/nereids_p0/eager_agg/eager_agg.out 
b/regression-test/data/nereids_p0/eager_agg/eager_agg.out
index 731f2e9bd9e..85d8dcffd15 100644
--- a/regression-test/data/nereids_p0/eager_agg/eager_agg.out
+++ b/regression-test/data/nereids_p0/eager_agg/eager_agg.out
@@ -311,3 +311,76 @@ Used:
 UnUsed:
 SyntaxError: leading({ ss broadcast dt } broadcast ws) Msg:can not find table: 
ws
 
+-- !check_sum_literal_right_join_not_push --
+PhysicalResultSink
+--hashAgg[GLOBAL]
+----hashAgg[LOCAL]
+------hashJoin[RIGHT_OUTER_JOIN] hashCondition=((a.val = c.val) and (b.id2 = 
c.id2)) otherCondition=()
+--------hashJoin[RIGHT_OUTER_JOIN] hashCondition=((a.id = b.id)) 
otherCondition=()
+----------PhysicalOlapScan[eager_agg_t1]
+----------PhysicalOlapScan[eager_agg_t2]
+--------PhysicalOlapScan[eager_agg_t3]
+
+-- !check_sum_literal_left_join_not_push --
+PhysicalResultSink
+--hashAgg[GLOBAL]
+----hashAgg[LOCAL]
+------hashJoin[LEFT_OUTER_JOIN] hashCondition=((date_dim.d_date_sk = 
store_sales.ss_sold_date_sk)) otherCondition=()
+--------hashAgg[GLOBAL]
+----------hashAgg[LOCAL]
+------------PhysicalOlapScan[store_sales]
+--------PhysicalOlapScan[date_dim]
+
+-- !check_min_literal_right_join_not_push --
+PhysicalResultSink
+--hashAgg[GLOBAL]
+----hashAgg[LOCAL]
+------hashJoin[RIGHT_OUTER_JOIN] hashCondition=((a.val = c.val) and (b.id2 = 
c.id2)) otherCondition=()
+--------hashJoin[RIGHT_OUTER_JOIN] hashCondition=((a.id = b.id)) 
otherCondition=()
+----------PhysicalOlapScan[eager_agg_t1]
+----------PhysicalOlapScan[eager_agg_t2]
+--------PhysicalOlapScan[eager_agg_t3]
+
+-- !check_max_literal_left_join_not_push --
+PhysicalResultSink
+--hashAgg[GLOBAL]
+----hashAgg[LOCAL]
+------hashJoin[LEFT_OUTER_JOIN] hashCondition=((date_dim.d_date_sk = 
store_sales.ss_sold_date_sk)) otherCondition=()
+--------hashAgg[GLOBAL]
+----------hashAgg[LOCAL]
+------------PhysicalOlapScan[store_sales]
+--------PhysicalOlapScan[date_dim]
+
+-- !sum_literal_right_join_eager_off --
+\N     4
+10     2
+
+-- !sum_literal_right_join_eager_on --
+\N     4
+10     2
+
+-- !min_literal_right_join_eager_on --
+\N     1
+10     1
+
+-- !max_literal_right_join_eager_on --
+\N     3
+10     3
+
+-- !check_filter_slots_preserved_pushdown --
+PhysicalResultSink
+--hashAgg[GLOBAL]
+----filter(OR[( not (id = 1)),id IS NULL])
+------hashJoin[LEFT_OUTER_JOIN] hashCondition=((a.id = b.id)) otherCondition=()
+--------hashAgg[GLOBAL]
+----------PhysicalOlapScan[eager_agg_filter_t1]
+--------PhysicalOlapScan[eager_agg_filter_t2]
+
+Hint log:
+Used: [broadcast]_1
+UnUsed:
+SyntaxError:
+
+-- !filter_slots_preserved_eager_on --
+2      20
+
diff --git a/regression-test/suites/nereids_p0/eager_agg/eager_agg.groovy 
b/regression-test/suites/nereids_p0/eager_agg/eager_agg.groovy
index 4f9653829b3..5d738a962d6 100644
--- a/regression-test/suites/nereids_p0/eager_agg/eager_agg.groovy
+++ b/regression-test/suites/nereids_p0/eager_agg/eager_agg.groovy
@@ -411,4 +411,156 @@ suite("eager_agg") {
     ) t
     group by d_year;
     """
+
+    // 
=========================================================================
+    // Tests for agg(literal) on nullable side of outer joins
+    // sum(literal), min(literal), max(literal) should NOT be pushed to the
+    // nullable side of outer joins because unmatched rows lose their 
contribution.
+    // 
=========================================================================
+
+    sql """
+        drop table if exists eager_agg_t1;
+        drop table if exists eager_agg_t2;
+        drop table if exists eager_agg_t3;
+        drop table if exists eager_agg_filter_t1;
+        drop table if exists eager_agg_filter_t2;
+
+        CREATE TABLE eager_agg_t1 (
+            id INT NOT NULL,
+            val INT
+        ) DISTRIBUTED BY HASH(id) BUCKETS 1
+        PROPERTIES ('replication_num' = '1');
+
+        CREATE TABLE eager_agg_t2 (
+            id INT NOT NULL,
+            id2 INT NOT NULL
+        ) DISTRIBUTED BY HASH(id) BUCKETS 1
+        PROPERTIES ('replication_num' = '1');
+
+        CREATE TABLE eager_agg_t3 (
+            id2 INT NOT NULL,
+            val INT
+        ) DISTRIBUTED BY HASH(id2) BUCKETS 1
+        PROPERTIES ('replication_num' = '1');
+
+        CREATE TABLE eager_agg_filter_t1 (
+            id INT NOT NULL,
+            flag INT NOT NULL,
+            v INT NOT NULL
+        ) DISTRIBUTED BY HASH(id) BUCKETS 1
+        PROPERTIES ('replication_num' = '1');
+
+        CREATE TABLE eager_agg_filter_t2 (
+            id INT NOT NULL
+        ) DISTRIBUTED BY HASH(id) BUCKETS 1
+        PROPERTIES ('replication_num' = '1');
+
+        INSERT INTO eager_agg_t1 VALUES (1, 10);
+        INSERT INTO eager_agg_t2 VALUES (1, 100), (2, 200);
+        INSERT INTO eager_agg_t3 VALUES (100, 10), (200, 20), (300, 30);
+        INSERT INTO eager_agg_filter_t1 VALUES (1, 0, 10), (2, 1, 20);
+        INSERT INTO eager_agg_filter_t2 VALUES (1);
+    """
+
+    // sum(literal) should NOT be pushed below RIGHT JOIN to the nullable left 
side
+    qt_check_sum_literal_right_join_not_push """
+    explain shape plan
+    select /*+SET_VAR(eager_aggregation_mode=1, disable_join_reorder = true)*/
+        a.val, sum(2) as s
+    from eager_agg_t1 as a
+    right join eager_agg_t2 as b on a.id = b.id
+    right join eager_agg_t3 as c on b.id2 = c.id2 and a.val = c.val
+    group by a.val;
+    """
+
+    // sum(literal) should NOT be pushed below LEFT JOIN to the nullable right 
side
+    qt_check_sum_literal_left_join_not_push """
+    explain shape plan
+    select /*+SET_VAR(eager_aggregation_mode=1, disable_join_reorder = true)*/
+        ss_sales_price, sum(2) as s
+    from store_sales
+    left join date_dim on d_date_sk = ss_sold_date_sk
+    group by ss_sales_price;
+    """
+
+    // min(literal) should NOT be pushed to nullable side of RIGHT JOIN
+    qt_check_min_literal_right_join_not_push """
+    explain shape plan
+    select /*+SET_VAR(eager_aggregation_mode=1, disable_join_reorder = true)*/
+        a.val, min(1) as m
+    from eager_agg_t1 as a
+    right join eager_agg_t2 as b on a.id = b.id
+    right join eager_agg_t3 as c on b.id2 = c.id2 and a.val = c.val
+    group by a.val;
+    """
+
+    // max(literal) should NOT be pushed to nullable side of LEFT JOIN
+    qt_check_max_literal_left_join_not_push """
+    explain shape plan
+    select /*+SET_VAR(eager_aggregation_mode=1, disable_join_reorder = true)*/
+        ss_sales_price, max(3) as m
+    from store_sales
+    left join date_dim on d_date_sk = ss_sold_date_sk
+    group by ss_sales_price;
+    """
+
+    // Execution tests: verify eager agg produces correct results for outer 
join + literal agg
+    order_qt_sum_literal_right_join_eager_off """
+    select /*+SET_VAR(eager_aggregation_mode=-1)*/ /*+ leading(a b c) */
+        a.val, sum(2) as s
+    from eager_agg_t1 as a
+    right join eager_agg_t2 as b on a.id = b.id
+    right join eager_agg_t3 as c on b.id2 = c.id2 and a.val = c.val
+    group by a.val
+    order by a.val;
+    """
+
+    order_qt_sum_literal_right_join_eager_on """
+    select /*+SET_VAR(eager_aggregation_mode=1)*/ /*+ leading(a b c) */
+        a.val, sum(2) as s
+    from eager_agg_t1 as a
+    right join eager_agg_t2 as b on a.id = b.id
+    right join eager_agg_t3 as c on b.id2 = c.id2 and a.val = c.val
+    group by a.val
+    order by a.val;
+    """
+
+    order_qt_min_literal_right_join_eager_on """
+    select /*+SET_VAR(eager_aggregation_mode=1)*/ /*+ leading(a b c) */
+        a.val, min(1) as m
+    from eager_agg_t1 as a
+    right join eager_agg_t2 as b on a.id = b.id
+    right join eager_agg_t3 as c on b.id2 = c.id2 and a.val = c.val
+    group by a.val
+    order by a.val;
+    """
+
+    order_qt_max_literal_right_join_eager_on """
+    select /*+SET_VAR(eager_aggregation_mode=1)*/ /*+ leading(a b c) */
+        a.val, max(3) as m
+    from eager_agg_t1 as a
+    right join eager_agg_t2 as b on a.id = b.id
+    right join eager_agg_t3 as c on b.id2 = c.id2 and a.val = c.val
+    group by a.val
+    order by a.val;
+    """
+
+    qt_check_filter_slots_preserved_pushdown """
+    explain shape plan
+    select /*+SET_VAR(eager_aggregation_mode=1, disable_join_reorder = true)*/
+        a.id, sum(a.v) as s
+    from eager_agg_filter_t1 as a
+    left join[broadcast] eager_agg_filter_t2 as b on a.id = b.id
+    where b.id <> 1 or b.id is null
+    group by a.id;
+    """
+
+    order_qt_filter_slots_preserved_eager_on """
+    select /*+SET_VAR(eager_aggregation_mode=1, disable_join_reorder = true)*/
+        a.id, sum(a.v) as s
+    from eager_agg_filter_t1 as a
+    left join[broadcast] eager_agg_filter_t2 as b on a.id = b.id
+    where b.id <> 1 or b.id is null
+    group by a.id;
+    """
 }


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

Reply via email to