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 e2e8661298c branch-4.1 [opt](nereids)push down assert one row join 
#57414 (#61484)
e2e8661298c is described below

commit e2e8661298cc72b2cf58ee591ea2c7643ccf8e68
Author: minghong <[email protected]>
AuthorDate: Thu Mar 19 10:58:34 2026 +0800

    branch-4.1 [opt](nereids)push down assert one row join #57414 (#61484)
    
    ### What problem does this PR solve?
    pick  #57414 #57804 #58174
    
    
    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 -->
---
 .../doris/nereids/jobs/executor/Rewriter.java      |   2 +
 .../org/apache/doris/nereids/rules/RuleType.java   |   1 +
 .../rules/rewrite/PushDownJoinOnAssertNumRows.java | 235 ++++++++++
 .../trees/plans/logical/LogicalProject.java        |  23 +
 .../rewrite/PushDownJoinOnAssertNumRowsTest.java   | 475 +++++++++++++++++++++
 .../tpcds_sf100/noStatsRfPrune/query54.out         |  76 ++--
 .../tpcds_sf100/no_stats_shape/query54.out         |  76 ++--
 .../shape_check/tpcds_sf100/rf_prune/query54.out   |  82 ++--
 .../data/shape_check/tpcds_sf100/shape/query54.out |  82 ++--
 .../tpcds_sf1000/bs_downgrade_shape/query54.out    |  82 ++--
 .../data/shape_check/tpcds_sf1000/hint/query54.out |  82 ++--
 .../shape_check/tpcds_sf1000/shape/query54.out     |  82 ++--
 .../shape_check/tpcds_sf10t_orc/shape/query54.out  |  76 ++--
 13 files changed, 1055 insertions(+), 319 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Rewriter.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Rewriter.java
index cd4d32b07b3..dad2ba0bae6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Rewriter.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/executor/Rewriter.java
@@ -135,6 +135,7 @@ import 
org.apache.doris.nereids.rules.rewrite.PushDownDistinctThroughJoin;
 import org.apache.doris.nereids.rules.rewrite.PushDownEncodeSlot;
 import org.apache.doris.nereids.rules.rewrite.PushDownFilterIntoSchemaScan;
 import org.apache.doris.nereids.rules.rewrite.PushDownFilterThroughProject;
+import org.apache.doris.nereids.rules.rewrite.PushDownJoinOnAssertNumRows;
 import org.apache.doris.nereids.rules.rewrite.PushDownLimit;
 import org.apache.doris.nereids.rules.rewrite.PushDownLimitDistinctThroughJoin;
 import 
org.apache.doris.nereids.rules.rewrite.PushDownLimitDistinctThroughUnion;
@@ -750,6 +751,7 @@ public class Rewriter extends AbstractBatchJobExecutor {
                 ),
                 topic("set initial join order",
                         bottomUp(ImmutableList.of(new InitJoinOrder())),
+                        bottomUp(ImmutableList.of(new 
PushDownJoinOnAssertNumRows(), new MergeProjectable())),
                         topDown(new SkewJoin())),
                 topic("agg rewrite",
                     // these rules should be put after mv optimization to 
avoid mv matching fail
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
index fff96b6935c..bbd91361b65 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
@@ -244,6 +244,7 @@ public enum RuleType {
     LOGICAL_SEMI_JOIN_COMMUTE(RuleTypeClass.REWRITE),
     TRANSPOSE_LOGICAL_SEMI_JOIN_AGG(RuleTypeClass.REWRITE),
     TRANSPOSE_LOGICAL_SEMI_JOIN_AGG_PROJECT(RuleTypeClass.REWRITE),
+    PUSH_DOWN_JOIN_ON_ASSERT_NUM_ROWS(RuleTypeClass.REWRITE),
 
     // expression of plan rewrite
     EXTRACT_IN_PREDICATE_FROM_OR(RuleTypeClass.REWRITE),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PushDownJoinOnAssertNumRows.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PushDownJoinOnAssertNumRows.java
new file mode 100644
index 00000000000..e52def0723c
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PushDownJoinOnAssertNumRows.java
@@ -0,0 +1,235 @@
+// 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.
+
+package org.apache.doris.nereids.rules.rewrite;
+
+import org.apache.doris.nereids.rules.Rule;
+import org.apache.doris.nereids.rules.RuleType;
+import org.apache.doris.nereids.trees.expressions.Alias;
+import org.apache.doris.nereids.trees.expressions.AssertNumRowsElement;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.NamedExpression;
+import org.apache.doris.nereids.trees.expressions.Slot;
+import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalAssertNumRows;
+import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
+import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Push down join when one child is LogicalAssertNumRows.
+ * select * from T1 join T2 where T1.b=T2.b and T1.a > (select x from T3 ...)
+ *
+ * <pre>
+ * Case 1: Push to left child
+ * Before:
+ *     topJoin(T1.a > x)
+ *       |-- Project
+ *       |     `-- bottomJoin(T1.b = T2.b)
+ *       |           |-- Scan(T1)
+ *       |           `-- Scan(T2)
+ *       `-- LogicalAssertNumRows(output=(x, ...))
+ *
+ * After:
+ *     Project
+ *       |-- topJoin(T1.b = T2.b)
+ *               |-- bottomJoin(T1.a > x)
+ *                   |-- Scan(T1)
+ *                   `-- LogicalAssertNumRows(output=(x, ...))
+ *               `-- Scan(T2)
+ *
+ * Case 2: Push to right child
+ * Before:
+ *     topJoin(T2.a > x)
+ *       |-- Project
+ *       |     `-- bottomJoin(T1.b = T2.b)
+ *       |           |-- Scan(T1)
+ *       |           `-- Scan(T2)
+ *       `-- LogicalAssertNumRows(output=(x, ...))
+ *
+ * After:
+ *     Project
+ *       |-- topJoin(T1.b = T2.b)
+ *              |--Scan(T1)
+ *             `-- bottomJoin(T2.a > x)
+ *                   |-- Scan(T2)
+ *                   `-- LogicalAssertNumRows(output=(x, ...))
+ * </pre>
+ */
+public class PushDownJoinOnAssertNumRows extends OneRewriteRuleFactory {
+    @Override
+    public Rule build() {
+        return logicalJoin()
+                .when(topJoin -> pattenCheck(topJoin))
+                .then(topJoin -> pushDownAssertNumRowsJoin(topJoin))
+                .toRule(RuleType.PUSH_DOWN_JOIN_ON_ASSERT_NUM_ROWS);
+    }
+
+    private boolean pattenCheck(LogicalJoin topJoin) {
+        // 1. right is LogicalAssertNumRows or 
LogicalProject->LogicalAssertNumRows
+        // 2. left is join or project->join
+        // 3. only one join condition.
+        if (!topJoin.getJoinType().isInnerOrCrossJoin()) {
+            return false;
+        }
+        LogicalJoin bottomJoin;
+        Plan left = topJoin.left();
+        Plan right = topJoin.right();
+        if (!isAssertOneRowEqOrProjectAssertOneRowEq(right)) {
+            return false;
+        }
+        if (left instanceof LogicalJoin) {
+            bottomJoin = (LogicalJoin) left;
+        } else if (left instanceof LogicalProject && left.child(0) instanceof 
LogicalJoin) {
+            bottomJoin = (LogicalJoin) left.child(0);
+        } else {
+            return false;
+        }
+
+        if (!bottomJoin.getJoinType().isInnerOrCrossJoin()) {
+            return false;
+        }
+
+        if (joinOnAssertOneRowEq(bottomJoin)) {
+            return false;
+        }
+
+        if (topJoin.getHashJoinConjuncts().isEmpty()) {
+            return topJoin.getOtherJoinConjuncts().size() == 1;
+        }
+        return false;
+    }
+
+    private boolean isAssertOneRowEqOrProjectAssertOneRowEq(Plan plan) {
+        if (plan instanceof LogicalProject) {
+            plan = plan.child(0);
+        }
+        if (plan instanceof LogicalAssertNumRows) {
+            AssertNumRowsElement assertNumRowsElement = 
((LogicalAssertNumRows) plan).getAssertNumRowsElement();
+            if (assertNumRowsElement.getAssertion() == 
AssertNumRowsElement.Assertion.EQ
+                    || assertNumRowsElement.getDesiredNumOfRows() == 1L) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean joinOnAssertOneRowEq(LogicalJoin join) {
+        return isAssertOneRowEqOrProjectAssertOneRowEq(join.right())
+                || isAssertOneRowEqOrProjectAssertOneRowEq(join.left());
+    }
+
+    private Plan pushDownAssertNumRowsJoin(LogicalJoin topJoin) {
+        Plan assertBranch = topJoin.right();
+        Expression condition = (Expression) 
topJoin.getOtherJoinConjuncts().get(0);
+        List<Alias> aliasUsedInConditionFromLeftProject = new ArrayList<>();
+        LogicalJoin<? extends Plan, ? extends Plan> bottomJoin;
+        if (topJoin.left() instanceof LogicalProject) {
+            LogicalProject<? extends Plan> leftProject = (LogicalProject<? 
extends Plan>) topJoin.left();
+            for (NamedExpression namedExpression : leftProject.getProjects()) {
+                if (namedExpression instanceof Alias && 
condition.getInputSlots().contains(namedExpression.toSlot())) {
+                    aliasUsedInConditionFromLeftProject.add((Alias) 
namedExpression);
+                }
+            }
+            condition = leftProject.pushDownExpressionPastProject(condition);
+            bottomJoin = (LogicalJoin<? extends Plan, ? extends Plan>) 
leftProject.child();
+        } else {
+            bottomJoin = (LogicalJoin<? extends Plan, ? extends Plan>) 
topJoin.left();
+        }
+        Plan bottomLeft = bottomJoin.left();
+        Plan bottomRight = bottomJoin.right();
+
+        List<Slot> conditionSlotsFromTopLeft = 
condition.getInputSlots().stream()
+                .filter(slot -> topJoin.left().getOutputSet().contains(slot))
+                .collect(Collectors.toList());
+        if (bottomLeft.getOutputSet().containsAll(conditionSlotsFromTopLeft)) {
+            // push to bottomLeft
+            Plan newBottomLeft;
+            if (aliasUsedInConditionFromLeftProject.isEmpty()) {
+                newBottomLeft = bottomLeft;
+            } else {
+                newBottomLeft = 
projectAliasOnPlan(aliasUsedInConditionFromLeftProject, bottomLeft);
+            }
+            LogicalJoin<? extends Plan, ? extends Plan> newBottomJoin = new 
LogicalJoin<>(
+                    topJoin.getJoinType(),
+                    topJoin.getHashJoinConjuncts(),
+                    topJoin.getOtherJoinConjuncts(),
+                    newBottomLeft,
+                    assertBranch,
+                    topJoin.getJoinReorderContext());
+            LogicalJoin<? extends Plan, ? extends Plan> newTopJoin = 
(LogicalJoin<? extends Plan, ? extends Plan>)
+                    bottomJoin.withChildren(newBottomJoin, bottomRight);
+            if (topJoin.left() instanceof LogicalProject) {
+                LogicalProject<? extends Plan> upperProject = 
projectAliasOnPlan(
+                        aliasUsedInConditionFromLeftProject, topJoin.left());
+                return upperProject.withChildren(newTopJoin);
+            } else {
+                return newTopJoin;
+            }
+        } else if 
(bottomRight.getOutputSet().containsAll(conditionSlotsFromTopLeft)) {
+            Plan newBottomRight;
+            if (aliasUsedInConditionFromLeftProject.isEmpty()) {
+                newBottomRight = bottomRight;
+            } else {
+                newBottomRight = 
projectAliasOnPlan(aliasUsedInConditionFromLeftProject, bottomRight);
+            }
+            LogicalJoin<? extends Plan, ? extends Plan> newBottomJoin = new 
LogicalJoin<>(
+                    topJoin.getJoinType(),
+                    topJoin.getHashJoinConjuncts(),
+                    topJoin.getOtherJoinConjuncts(),
+                    newBottomRight,
+                    assertBranch,
+                    topJoin.getJoinReorderContext());
+            LogicalJoin<? extends Plan, ? extends Plan> newTopJoin = 
(LogicalJoin<? extends Plan, ? extends Plan>)
+                    bottomJoin.withChildren(bottomLeft, newBottomJoin);
+            if (topJoin.left() instanceof LogicalProject) {
+                LogicalProject<? extends Plan> upperProject = 
projectAliasOnPlan(
+                        aliasUsedInConditionFromLeftProject, topJoin.left());
+                return upperProject.withChildren(newTopJoin);
+            } else {
+                return newTopJoin;
+            }
+        }
+        return null;
+    }
+
+    @VisibleForTesting
+    LogicalProject<? extends Plan> projectAliasOnPlan(List<Alias> projections, 
Plan child) {
+        if (child instanceof LogicalProject) {
+            LogicalProject<? extends Plan> project = (LogicalProject<? extends 
Plan>) child;
+            List<NamedExpression> newProjections =
+                    Lists.newArrayList(project.getProjects());
+            for (Alias alias : projections) {
+                if (!project.getOutput().contains(alias.toSlot())) {
+                    NamedExpression expr = (NamedExpression) 
project.pushDownExpressionPastProject(alias);
+                    newProjections.add(expr);
+                }
+            }
+            return project.withProjects(newProjections);
+        } else {
+            List<NamedExpression> newProjections = 
Lists.newArrayList(child.getOutput());
+            newProjections.addAll(projections);
+            return new LogicalProject<>(newProjections, child);
+        }
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalProject.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalProject.java
index 6925bcf8fe7..2aef066bba8 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalProject.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalProject.java
@@ -62,6 +62,7 @@ public class LogicalProject<CHILD_TYPE extends Plan> extends 
LogicalUnary<CHILD_
     private final List<NamedExpression> projects;
     private final Supplier<Set<NamedExpression>> projectsSet;
     private final boolean isDistinct;
+    private final HashMap projectMap;
 
     public LogicalProject(List<NamedExpression> projects, CHILD_TYPE child) {
         this(projects, false, ImmutableList.of(child));
@@ -90,6 +91,17 @@ public class LogicalProject<CHILD_TYPE extends Plan> extends 
LogicalUnary<CHILD_
                 : projects;
         this.projectsSet = Suppliers.memoize(() -> 
Utils.fastToImmutableSet(this.projects));
         this.isDistinct = isDistinct;
+        this.projectMap = new HashMap<>();
+        for (NamedExpression namedExpression : projects) {
+            if (namedExpression.hasUnbound()) {
+                projectMap.clear();
+                break;
+            }
+            if (namedExpression instanceof Alias) {
+                Alias alias = (Alias) namedExpression;
+                projectMap.put(alias.toSlot(), alias.child());
+            }
+        }
     }
 
     /**
@@ -305,4 +317,15 @@ public class LogicalProject<CHILD_TYPE extends Plan> 
extends LogicalUnary<CHILD_
             builder.addDeps(expr.getInputSlots(), 
ImmutableSet.of(expr.toSlot()));
         }
     }
+
+    /**
+     * example:
+     * expression: x + 1
+     * project(a+b as x)
+     * then before project, the expression is a+b+1
+     *
+     */
+    public Expression pushDownExpressionPastProject(Expression expression) {
+        return ExpressionUtils.replace(expression, projectMap);
+    }
 }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/PushDownJoinOnAssertNumRowsTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/PushDownJoinOnAssertNumRowsTest.java
new file mode 100644
index 00000000000..aded31bd18f
--- /dev/null
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/PushDownJoinOnAssertNumRowsTest.java
@@ -0,0 +1,475 @@
+// 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.
+
+package org.apache.doris.nereids.rules.rewrite;
+
+import org.apache.doris.nereids.trees.expressions.Add;
+import org.apache.doris.nereids.trees.expressions.Alias;
+import org.apache.doris.nereids.trees.expressions.AssertNumRowsElement;
+import 
org.apache.doris.nereids.trees.expressions.AssertNumRowsElement.Assertion;
+import org.apache.doris.nereids.trees.expressions.EqualTo;
+import org.apache.doris.nereids.trees.expressions.ExprId;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.GreaterThan;
+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.literal.Literal;
+import org.apache.doris.nereids.trees.plans.JoinType;
+import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.RelationId;
+import org.apache.doris.nereids.trees.plans.logical.LogicalAssertNumRows;
+import org.apache.doris.nereids.trees.plans.logical.LogicalEmptyRelation;
+import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
+import org.apache.doris.nereids.types.IntegerType;
+import org.apache.doris.nereids.util.LogicalPlanBuilder;
+import org.apache.doris.nereids.util.MemoPatternMatchSupported;
+import org.apache.doris.nereids.util.MemoTestUtils;
+import org.apache.doris.nereids.util.PlanChecker;
+import org.apache.doris.nereids.util.PlanConstructor;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import java.util.List;
+
+/**
+ * Test for PushDownJoinOnAssertNumRows rule.
+ */
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class PushDownJoinOnAssertNumRowsTest implements MemoPatternMatchSupported {
+
+    private LogicalOlapScan t1;
+    private LogicalOlapScan t2;
+    private LogicalOlapScan t3;
+
+    private List<Slot> t1Slots;
+    private List<Slot> t2Slots;
+    private List<Slot> t3Slots;
+
+    /**
+     * Setup test fixtures.
+     */
+    @BeforeAll
+    final void beforeAll() {
+        t1 = new LogicalOlapScan(PlanConstructor.getNextRelationId(), 
PlanConstructor.student,
+        ImmutableList.of(""));
+        t2 = new LogicalOlapScan(PlanConstructor.getNextRelationId(), 
PlanConstructor.score,
+        ImmutableList.of(""));
+        t3 = new LogicalOlapScan(PlanConstructor.getNextRelationId(), 
PlanConstructor.course,
+        ImmutableList.of(""));
+        t1Slots = t1.getOutput();
+        t2Slots = t2.getOutput();
+        t3Slots = t3.getOutput();
+    }
+
+    /**
+     * Test basic push down to left child scenario:
+     * Before:
+     * topJoin(T1.a > x)
+     * |-- bottomJoin(T1.b = T2.b)
+     * | |-- Scan(T1)
+     * | `-- Scan(T2)
+     * `-- LogicalAssertNumRows(output=(x, ...))
+     *
+     * After:
+     * bottomJoin(T1.b = T2.b)
+     * |-- topJoin(T1.a > x)
+     * | |-- Scan(T1)
+     * | `-- LogicalAssertNumRows(output=(x, ...))
+     * `-- Scan(T2)
+     */
+    @Test
+    void testPushDownToLeftChild() {
+        // Create a one-row relation wrapped in LogicalAssertNumRows
+        Plan oneRowRelation = new LogicalPlanBuilder(t3)
+                .limit(1)
+                .build();
+
+        AssertNumRowsElement assertElement = new AssertNumRowsElement(1, "", 
Assertion.EQ);
+        LogicalAssertNumRows<Plan> assertNumRows = new 
LogicalAssertNumRows<>(assertElement, oneRowRelation);
+
+        // Create bottom join: T1 JOIN T2 on T1.id = T2.sid
+        Expression bottomJoinCondition = new EqualTo(t1Slots.get(0), 
t2Slots.get(1));
+
+        LogicalPlan bottomJoin = new LogicalPlanBuilder(t1)
+                .join(t2, JoinType.INNER_JOIN, 
ImmutableList.of(bottomJoinCondition),
+                                ImmutableList.of())
+                .build();
+
+        // Create top join: (T1 JOIN T2) JOIN assertNumRows on T1.age > 
course.id
+        Expression topJoinCondition = new GreaterThan(t1Slots.get(1), 
t3Slots.get(0));
+
+        LogicalPlan root = new LogicalPlanBuilder(bottomJoin)
+                .join(assertNumRows, JoinType.INNER_JOIN, ImmutableList.of(),
+                                ImmutableList.of(topJoinCondition))
+                .build();
+
+        // Apply the rule
+        PlanChecker.from(MemoTestUtils.createConnectContext(), root)
+                .applyTopDown(new PushDownJoinOnAssertNumRows())
+                .matches(logicalJoin(
+                                logicalJoin(
+                                                        logicalOlapScan(),
+                                                        
logicalAssertNumRows()),
+                                logicalOlapScan()));
+    }
+
+    /**
+     * Test push down to right child scenario:
+     * Before:
+     * topJoin(T2.a > x)
+     * |-- bottomJoin(T1.b = T2.b)
+     * | |-- Scan(T1)
+     * | `-- Scan(T2)
+     * `-- LogicalAssertNumRows(output=(x, ...))
+     *
+     * After:
+     * bottomJoin(T1.b = T2.b)
+     * |-- Scan(T1)
+     * `-- topJoin(T2.a > x)
+     * |-- Scan(T2)
+     * `-- LogicalAssertNumRows(output=(x, ...))
+     */
+    @Test
+    void testPushDownToRightChild() {
+        // Create a one-row relation wrapped in LogicalAssertNumRows
+        Plan oneRowRelation = new LogicalPlanBuilder(t3)
+                .limit(1)
+                .build();
+
+        AssertNumRowsElement assertElement = new AssertNumRowsElement(1, "", 
Assertion.EQ);
+        LogicalAssertNumRows<Plan> assertNumRows = new 
LogicalAssertNumRows<>(assertElement, oneRowRelation);
+
+        // Create bottom join: T1 JOIN T2 on T1.id = T2.sid
+        Expression bottomJoinCondition = new EqualTo(t1Slots.get(0), 
t2Slots.get(1));
+
+        LogicalPlan bottomJoin = new LogicalPlanBuilder(t1)
+                .join(t2, JoinType.INNER_JOIN, 
ImmutableList.of(bottomJoinCondition),
+                                ImmutableList.of())
+                .build();
+
+        // Create top join: (T1 JOIN T2) JOIN assertNumRows on T2.name > 
course.name
+        // This references T2 (right child of bottom join) and assertNumRows
+        Expression topJoinCondition = new GreaterThan(t2Slots.get(2), 
t3Slots.get(1));
+
+        LogicalPlan root = new LogicalPlanBuilder(bottomJoin)
+                .join(assertNumRows, JoinType.INNER_JOIN, ImmutableList.of(),
+                                ImmutableList.of(topJoinCondition))
+                .build();
+
+        // Apply the rule
+        PlanChecker.from(MemoTestUtils.createConnectContext(), root)
+                .applyTopDown(new PushDownJoinOnAssertNumRows())
+                .matches(logicalJoin(
+                                logicalOlapScan(),
+                                logicalJoin(
+                                                        logicalOlapScan(),
+                                                        
logicalAssertNumRows())));
+    }
+
+    /**
+     * Test with project node between top join and bottom join:
+     * Before:
+     * topJoin(alias_col > x)
+     * |-- Project(T1.id, T1.age + 1 as alias_col, ...)
+     * | `-- bottomJoin(T1.id = T2.sid)
+     * | |-- Scan(T1)
+     * | `-- Scan(T2)
+     * `-- LogicalAssertNumRows(output=(x, ...))
+     *
+     * After:
+     * Project(...)
+     * |-- bottomJoin(T1.id = T2.sid)
+     * |-- topJoin(T1.age + 1 > x)
+     * | |-- Scan(T1)
+     * | `-- LogicalAssertNumRows(output=(x, ...))
+     * `-- Scan(T2)
+     */
+    @Test
+    void testPushDownWithProjectNode() {
+        // Create a one-row relation wrapped in LogicalAssertNumRows
+        Plan oneRowRelation = new LogicalPlanBuilder(t3)
+                .limit(1)
+                .build();
+
+        AssertNumRowsElement assertElement = new AssertNumRowsElement(1, "", 
Assertion.EQ);
+        LogicalAssertNumRows<Plan> assertNumRows = new 
LogicalAssertNumRows<>(assertElement, oneRowRelation);
+
+        // Create bottom join: T1 JOIN T2 on T1.id = T2.sid
+        Expression bottomJoinCondition = new EqualTo(t1Slots.get(0), 
t2Slots.get(1));
+
+        LogicalPlan bottomJoin = new LogicalPlanBuilder(t1)
+                .join(t2, JoinType.INNER_JOIN, 
ImmutableList.of(bottomJoinCondition),
+                                ImmutableList.of())
+                .build();
+
+        // Create project with alias: T1.age + 1 as alias_col
+        Expression addExpr = new Add(t1Slots.get(1), Literal.of(1));
+        Alias aliasCol = new Alias(addExpr, "alias_col");
+
+        ImmutableList.Builder<NamedExpression> projectListBuilder = 
ImmutableList.builder();
+        projectListBuilder.add(t1Slots.get(0)); // T1.id
+        projectListBuilder.add(aliasCol); // T1.age + 1 as alias_col
+        projectListBuilder.addAll(t2Slots); // All T2 columns
+
+        LogicalProject<Plan> project = new 
LogicalProject<>(projectListBuilder.build(), bottomJoin);
+
+        // Create top join: project JOIN assertNumRows on alias_col > course.id
+        Expression topJoinCondition = new GreaterThan(aliasCol.toSlot(), 
t3Slots.get(0));
+
+        LogicalPlan root = new LogicalPlanBuilder(project)
+                .join(assertNumRows, JoinType.INNER_JOIN, ImmutableList.of(),
+                                ImmutableList.of(topJoinCondition))
+                .build();
+
+        // Apply the rule
+        PlanChecker.from(MemoTestUtils.createConnectContext(), root)
+                .applyTopDown(new PushDownJoinOnAssertNumRows())
+                .matches(logicalProject(
+                                logicalJoin(
+                                                        logicalJoin(
+                                                                        
logicalProject(logicalOlapScan()),
+                                                                        
logicalAssertNumRows()),
+                                                        logicalOlapScan())));
+    }
+
+    /**
+     * Test with CROSS JOIN type.
+     */
+    @Test
+    void testWithCrossJoin() {
+        // Create a one-row relation wrapped in LogicalAssertNumRows
+        Plan oneRowRelation = new LogicalPlanBuilder(t3)
+                .limit(1)
+                .build();
+
+        AssertNumRowsElement assertElement = new AssertNumRowsElement(1, "", 
Assertion.EQ);
+        LogicalAssertNumRows<Plan> assertNumRows = new 
LogicalAssertNumRows<>(assertElement, oneRowRelation);
+
+        // Create bottom cross join: T1 CROSS JOIN T2
+        LogicalPlan bottomJoin = new LogicalPlanBuilder(t1)
+                .join(t2, JoinType.CROSS_JOIN, ImmutableList.of(), 
ImmutableList.of())
+                .build();
+
+        // Create top join with condition: T1.age > course.id
+        Expression topJoinCondition = new GreaterThan(t1Slots.get(1), 
t3Slots.get(0));
+
+        LogicalPlan root = new LogicalPlanBuilder(bottomJoin)
+                .join(assertNumRows, JoinType.CROSS_JOIN, ImmutableList.of(),
+                                ImmutableList.of(topJoinCondition))
+                .build();
+
+        // Apply the rule
+        PlanChecker.from(MemoTestUtils.createConnectContext(), root)
+                .applyTopDown(new PushDownJoinOnAssertNumRows())
+                .matches(logicalJoin(
+                                logicalJoin(
+                                                        logicalOlapScan(),
+                                                        
logicalAssertNumRows()),
+                                logicalOlapScan()));
+    }
+
+    /**
+     * Test that rule doesn't apply when bottom join already has assertNumRows.
+     */
+    @Test
+    void testNoApplyWhenBottomJoinHasAssertNumRows() {
+        // Create two one-row relations
+        Plan oneRowRelation1 = new LogicalPlanBuilder(t2)
+                .limit(1)
+                .build();
+        Plan oneRowRelation2 = new LogicalPlanBuilder(t3)
+                .limit(1)
+                .build();
+
+        AssertNumRowsElement assertElement1 = new AssertNumRowsElement(1, "", 
Assertion.EQ);
+        AssertNumRowsElement assertElement2 = new AssertNumRowsElement(1, "", 
Assertion.EQ);
+        LogicalAssertNumRows<Plan> assertNumRows1 = new 
LogicalAssertNumRows<>(assertElement1, oneRowRelation1);
+        LogicalAssertNumRows<Plan> assertNumRows2 = new 
LogicalAssertNumRows<>(assertElement2, oneRowRelation2);
+
+        // Create bottom join that already has assertNumRows: T1 JOIN 
assertNumRows1
+        Expression bottomJoinCondition = new GreaterThan(t1Slots.get(1), 
t2Slots.get(0));
+
+        LogicalPlan bottomJoin = new LogicalPlanBuilder(t1)
+                .join(assertNumRows1, JoinType.INNER_JOIN, ImmutableList.of(),
+                                ImmutableList.of(bottomJoinCondition))
+                .build();
+
+        // Create top join with another assertNumRows
+        Expression topJoinCondition = new GreaterThan(t1Slots.get(1), 
t3Slots.get(0));
+
+        LogicalPlan root = new LogicalPlanBuilder(bottomJoin)
+                .join(assertNumRows2, JoinType.INNER_JOIN, ImmutableList.of(),
+                                ImmutableList.of(topJoinCondition))
+                .build();
+
+        // Apply the rule - should not transform because bottom join already 
has
+        // assertNumRows
+        PlanChecker.from(MemoTestUtils.createConnectContext(), root)
+                .applyTopDown(new PushDownJoinOnAssertNumRows())
+                .matches(logicalJoin(
+                                logicalJoin(
+                                                        logicalOlapScan(),
+                                                        
logicalAssertNumRows()),
+                                logicalAssertNumRows()));
+    }
+
+    /**
+     * Test that rule doesn't apply when there are multiple join conditions.
+     */
+    @Test
+    void testNoApplyWithMultipleJoinConditions() {
+        // Create a one-row relation wrapped in LogicalAssertNumRows
+        Plan oneRowRelation = new LogicalPlanBuilder(t3)
+                .limit(1)
+                .build();
+
+        AssertNumRowsElement assertElement = new AssertNumRowsElement(1, "", 
Assertion.EQ);
+        LogicalAssertNumRows<Plan> assertNumRows = new 
LogicalAssertNumRows<>(assertElement, oneRowRelation);
+
+        // Create bottom join: T1 JOIN T2 on T1.id = T2.sid
+        Expression bottomJoinCondition = new EqualTo(t1Slots.get(0), 
t2Slots.get(1));
+
+        LogicalPlan bottomJoin = new LogicalPlanBuilder(t1)
+                .join(t2, JoinType.INNER_JOIN, 
ImmutableList.of(bottomJoinCondition),
+                                ImmutableList.of())
+                .build();
+
+        // Create top join with multiple conditions
+        Expression topJoinCondition1 = new GreaterThan(t1Slots.get(1), 
t3Slots.get(0));
+        Expression topJoinCondition2 = new GreaterThan(t2Slots.get(0), 
t3Slots.get(0));
+
+        LogicalPlan root = new LogicalPlanBuilder(bottomJoin)
+                .join(assertNumRows, JoinType.INNER_JOIN, ImmutableList.of(),
+                                ImmutableList.of(topJoinCondition1, 
topJoinCondition2))
+                .build();
+
+        // Apply the rule - should not transform because there are multiple 
join
+        // conditions
+        PlanChecker.from(MemoTestUtils.createConnectContext(), root)
+                .applyTopDown(new PushDownJoinOnAssertNumRows())
+                .matches(logicalJoin(
+                                logicalJoin(
+                                                        logicalOlapScan(),
+                                                        logicalOlapScan()),
+                                logicalAssertNumRows()));
+    }
+
+    /**
+     * Test that rule doesn't apply with outer join types.
+     */
+    @Test
+    void testNoApplyWithOuterJoin() {
+        // Create a one-row relation wrapped in LogicalAssertNumRows
+        Plan oneRowRelation = new LogicalPlanBuilder(t3)
+                .limit(1)
+                .build();
+
+        AssertNumRowsElement assertElement = new AssertNumRowsElement(1, "", 
Assertion.EQ);
+        LogicalAssertNumRows<Plan> assertNumRows = new 
LogicalAssertNumRows<>(assertElement, oneRowRelation);
+
+        // Create bottom left outer join: T1 LEFT JOIN T2 on T1.id = T2.sid
+        Expression bottomJoinCondition = new EqualTo(t1Slots.get(0), 
t2Slots.get(1));
+
+        LogicalPlan bottomJoin = new LogicalPlanBuilder(t1)
+                .join(t2, JoinType.LEFT_OUTER_JOIN, 
ImmutableList.of(bottomJoinCondition),
+                                ImmutableList.of())
+                .build();
+
+        // Create top join with condition
+        Expression topJoinCondition = new GreaterThan(t1Slots.get(1), 
t3Slots.get(0));
+
+        LogicalPlan root = new LogicalPlanBuilder(bottomJoin)
+                .join(assertNumRows, JoinType.INNER_JOIN, ImmutableList.of(),
+                                ImmutableList.of(topJoinCondition))
+                .build();
+
+        // Apply the rule - should not transform because bottom join is outer 
join
+        PlanChecker.from(MemoTestUtils.createConnectContext(), root)
+                .applyTopDown(new PushDownJoinOnAssertNumRows())
+                .matches(logicalJoin(
+                                logicalJoin(
+                                                        logicalOlapScan(),
+                                                        logicalOlapScan()),
+                                logicalAssertNumRows()));
+    }
+
+    /**
+     * Test with assertNumRows wrapped in project.
+     */
+    @Test
+    void testWithAssertNumRowsInProject() {
+        // Create a one-row relation wrapped in LogicalAssertNumRows and then 
Project
+        Plan oneRowRelation = new LogicalPlanBuilder(t3)
+                .limit(1)
+                .build();
+
+        AssertNumRowsElement assertElement = new AssertNumRowsElement(1, "", 
Assertion.EQ);
+        LogicalAssertNumRows<Plan> assertNumRows = new 
LogicalAssertNumRows<>(assertElement, oneRowRelation);
+
+        // Wrap assertNumRows in a project
+        LogicalProject<Plan> assertProject = new LogicalProject<>(
+                ImmutableList.copyOf(assertNumRows.getOutput()), 
assertNumRows);
+
+        // Create bottom join: T1 JOIN T2 on T1.id = T2.sid
+        Expression bottomJoinCondition = new EqualTo(t1Slots.get(0), 
t2Slots.get(1));
+
+        LogicalPlan bottomJoin = new LogicalPlanBuilder(t1)
+                .join(t2, JoinType.INNER_JOIN, 
ImmutableList.of(bottomJoinCondition),
+                                ImmutableList.of())
+                .build();
+
+        // Create top join with project-wrapped assertNumRows
+        Expression topJoinCondition = new GreaterThan(t1Slots.get(1), 
t3Slots.get(0));
+
+        LogicalPlan root = new LogicalPlanBuilder(bottomJoin)
+                .join(assertProject, JoinType.INNER_JOIN, ImmutableList.of(),
+                                ImmutableList.of(topJoinCondition))
+                .build();
+
+        // Apply the rule
+        PlanChecker.from(MemoTestUtils.createConnectContext(), root)
+                .applyTopDown(new PushDownJoinOnAssertNumRows())
+                .matches(logicalJoin(
+                                logicalJoin(
+                                                        logicalOlapScan(),
+                                                        logicalProject(
+                                                                        
logicalAssertNumRows())),
+                                logicalOlapScan()));
+    }
+
+    @Test
+    void testProjectAliasOnPlan() {
+        PushDownJoinOnAssertNumRows rule = new PushDownJoinOnAssertNumRows();
+        Slot slot = new SlotReference(new ExprId(0), "data_slot", 
IntegerType.INSTANCE,
+                false, ImmutableList.of());
+        LogicalProject childProject = new 
LogicalProject(ImmutableList.of(slot),
+                new LogicalEmptyRelation(new RelationId(0), 
ImmutableList.of()));
+        Alias alias = new Alias(new ExprId(1), slot);
+        LogicalPlan newPlan = rule.projectAliasOnPlan(ImmutableList.of(alias), 
childProject);
+        Assertions.assertTrue(newPlan instanceof LogicalProject
+                && newPlan.getOutput().size() == 2
+                && ((LogicalProject<?>) 
newPlan).getOutputs().get(0).equals(slot)
+                && ((LogicalProject<?>) 
newPlan).getOutputs().get(1).equals(alias));
+    }
+}
diff --git 
a/regression-test/data/shape_check/tpcds_sf100/noStatsRfPrune/query54.out 
b/regression-test/data/shape_check/tpcds_sf100/noStatsRfPrune/query54.out
index 46ff85eba23..84b5754b67a 100644
--- a/regression-test/data/shape_check/tpcds_sf100/noStatsRfPrune/query54.out
+++ b/regression-test/data/shape_check/tpcds_sf100/noStatsRfPrune/query54.out
@@ -11,48 +11,56 @@ PhysicalResultSink
 ----------------PhysicalProject
 ------------------hashAgg[GLOBAL]
 --------------------PhysicalProject
-----------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as BIGINT) 
<= d_month_seq+3)
+----------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=()
 ------------------------PhysicalProject
---------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) >= d_month_seq+1)
+--------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=()
 ----------------------------PhysicalProject
-------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=()
+------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=()
 --------------------------------PhysicalProject
-----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=()
+----------------------------------hashJoin[INNER_JOIN shuffleBucket] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF3 c_customer_sk->[ss_customer_sk]
 ------------------------------------PhysicalProject
---------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=()
+--------------------------------------PhysicalOlapScan[store_sales] apply RFs: 
RF3
+------------------------------------PhysicalProject
+--------------------------------------hashAgg[GLOBAL]
 ----------------------------------------PhysicalProject
-------------------------------------------hashJoin[INNER_JOIN shuffleBucket] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF3 c_customer_sk->[ss_customer_sk]
---------------------------------------------PhysicalProject
-----------------------------------------------PhysicalOlapScan[store_sales] 
apply RFs: RF3
+------------------------------------------hashJoin[INNER_JOIN shuffle] 
hashCondition=((customer.c_customer_sk = cs_or_ws_sales.customer_sk)) 
otherCondition=()
 --------------------------------------------PhysicalProject
-----------------------------------------------hashAgg[GLOBAL]
+----------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
 ------------------------------------------------PhysicalProject
---------------------------------------------------hashJoin[INNER_JOIN shuffle] 
hashCondition=((customer.c_customer_sk = cs_or_ws_sales.customer_sk)) 
otherCondition=()
-----------------------------------------------------PhysicalProject
-------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
+--------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
+----------------------------------------------------PhysicalUnion
+------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 --------------------------------------------------------PhysicalProject
-----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
-------------------------------------------------------------PhysicalUnion
---------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
---------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------filter((item.i_category
 = 'Women') and (item.i_class = 'maternity'))
-----------------------------------------------------------------PhysicalOlapScan[item]
+----------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
+------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 --------------------------------------------------------PhysicalProject
-----------------------------------------------------------filter((date_dim.d_moy
 = 5) and (date_dim.d_year = 1998))
-------------------------------------------------------------PhysicalOlapScan[date_dim]
+----------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
 ----------------------------------------------------PhysicalProject
-------------------------------------------------------PhysicalOlapScan[customer]
-----------------------------------------PhysicalProject
-------------------------------------------PhysicalOlapScan[customer_address]
-------------------------------------PhysicalProject
---------------------------------------PhysicalOlapScan[store]
+------------------------------------------------------filter((item.i_category 
= 'Women') and (item.i_class = 'maternity'))
+--------------------------------------------------------PhysicalOlapScan[item]
+------------------------------------------------PhysicalProject
+--------------------------------------------------filter((date_dim.d_moy = 5) 
and (date_dim.d_year = 1998))
+----------------------------------------------------PhysicalOlapScan[date_dim]
+--------------------------------------------PhysicalProject
+----------------------------------------------PhysicalOlapScan[customer]
+--------------------------------PhysicalProject
+----------------------------------PhysicalOlapScan[customer_address]
+----------------------------PhysicalProject
+------------------------------PhysicalOlapScan[store]
+------------------------PhysicalProject
+--------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+----------------------------PhysicalProject
+------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) >= d_month_seq+1)
 --------------------------------PhysicalProject
 ----------------------------------PhysicalOlapScan[date_dim]
+--------------------------------PhysicalAssertNumRows
+----------------------------------PhysicalDistribute[DistributionSpecGather]
+------------------------------------hashAgg[GLOBAL]
+--------------------------------------PhysicalDistribute[DistributionSpecHash]
+----------------------------------------hashAgg[LOCAL]
+------------------------------------------PhysicalProject
+--------------------------------------------filter((date_dim.d_moy = 5) and 
(date_dim.d_year = 1998))
+----------------------------------------------PhysicalOlapScan[date_dim]
 ----------------------------PhysicalAssertNumRows
 ------------------------------PhysicalDistribute[DistributionSpecGather]
 --------------------------------hashAgg[GLOBAL]
@@ -61,12 +69,4 @@ PhysicalResultSink
 --------------------------------------PhysicalProject
 ----------------------------------------filter((date_dim.d_moy = 5) and 
(date_dim.d_year = 1998))
 ------------------------------------------PhysicalOlapScan[date_dim]
-------------------------PhysicalAssertNumRows
---------------------------PhysicalDistribute[DistributionSpecGather]
-----------------------------hashAgg[GLOBAL]
-------------------------------PhysicalDistribute[DistributionSpecHash]
---------------------------------hashAgg[LOCAL]
-----------------------------------PhysicalProject
-------------------------------------filter((date_dim.d_moy = 5) and 
(date_dim.d_year = 1998))
---------------------------------------PhysicalOlapScan[date_dim]
 
diff --git 
a/regression-test/data/shape_check/tpcds_sf100/no_stats_shape/query54.out 
b/regression-test/data/shape_check/tpcds_sf100/no_stats_shape/query54.out
index 0be42521255..a2a326baf8f 100644
--- a/regression-test/data/shape_check/tpcds_sf100/no_stats_shape/query54.out
+++ b/regression-test/data/shape_check/tpcds_sf100/no_stats_shape/query54.out
@@ -11,48 +11,56 @@ PhysicalResultSink
 ----------------PhysicalProject
 ------------------hashAgg[GLOBAL]
 --------------------PhysicalProject
-----------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as BIGINT) 
<= d_month_seq+3)
+----------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
 ------------------------PhysicalProject
---------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) >= d_month_seq+1)
+--------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF5 
s_county->[ca_county];RF6 s_state->[ca_state]
 ----------------------------PhysicalProject
-------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
+------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF4 
ca_address_sk->[c_current_addr_sk]
 --------------------------------PhysicalProject
-----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF5 
s_county->[ca_county];RF6 s_state->[ca_state]
+----------------------------------hashJoin[INNER_JOIN shuffleBucket] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF3 c_customer_sk->[ss_customer_sk]
 ------------------------------------PhysicalProject
---------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF4 
ca_address_sk->[c_current_addr_sk]
+--------------------------------------PhysicalOlapScan[store_sales] apply RFs: 
RF3 RF7
+------------------------------------PhysicalProject
+--------------------------------------hashAgg[GLOBAL]
 ----------------------------------------PhysicalProject
-------------------------------------------hashJoin[INNER_JOIN shuffleBucket] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF3 c_customer_sk->[ss_customer_sk]
---------------------------------------------PhysicalProject
-----------------------------------------------PhysicalOlapScan[store_sales] 
apply RFs: RF3 RF7
+------------------------------------------hashJoin[INNER_JOIN shuffle] 
hashCondition=((customer.c_customer_sk = cs_or_ws_sales.customer_sk)) 
otherCondition=() build RFs:RF2 
c_customer_sk->[cs_bill_customer_sk,ws_bill_customer_sk]
 --------------------------------------------PhysicalProject
-----------------------------------------------hashAgg[GLOBAL]
+----------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
 ------------------------------------------------PhysicalProject
---------------------------------------------------hashJoin[INNER_JOIN shuffle] 
hashCondition=((customer.c_customer_sk = cs_or_ws_sales.customer_sk)) 
otherCondition=() build RFs:RF2 
c_customer_sk->[cs_bill_customer_sk,ws_bill_customer_sk]
-----------------------------------------------------PhysicalProject
-------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
+--------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
+----------------------------------------------------PhysicalUnion
+------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 --------------------------------------------------------PhysicalProject
-----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
-------------------------------------------------------------PhysicalUnion
---------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1 RF2
---------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1 RF2
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------filter((item.i_category
 = 'Women') and (item.i_class = 'maternity'))
-----------------------------------------------------------------PhysicalOlapScan[item]
+----------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1 RF2
+------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 --------------------------------------------------------PhysicalProject
-----------------------------------------------------------filter((date_dim.d_moy
 = 5) and (date_dim.d_year = 1998))
-------------------------------------------------------------PhysicalOlapScan[date_dim]
+----------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1 RF2
 ----------------------------------------------------PhysicalProject
-------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF4
-----------------------------------------PhysicalProject
-------------------------------------------PhysicalOlapScan[customer_address] 
apply RFs: RF5 RF6
-------------------------------------PhysicalProject
---------------------------------------PhysicalOlapScan[store]
+------------------------------------------------------filter((item.i_category 
= 'Women') and (item.i_class = 'maternity'))
+--------------------------------------------------------PhysicalOlapScan[item]
+------------------------------------------------PhysicalProject
+--------------------------------------------------filter((date_dim.d_moy = 5) 
and (date_dim.d_year = 1998))
+----------------------------------------------------PhysicalOlapScan[date_dim]
+--------------------------------------------PhysicalProject
+----------------------------------------------PhysicalOlapScan[customer] apply 
RFs: RF4
+--------------------------------PhysicalProject
+----------------------------------PhysicalOlapScan[customer_address] apply 
RFs: RF5 RF6
+----------------------------PhysicalProject
+------------------------------PhysicalOlapScan[store]
+------------------------PhysicalProject
+--------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+----------------------------PhysicalProject
+------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) >= d_month_seq+1)
 --------------------------------PhysicalProject
 ----------------------------------PhysicalOlapScan[date_dim]
+--------------------------------PhysicalAssertNumRows
+----------------------------------PhysicalDistribute[DistributionSpecGather]
+------------------------------------hashAgg[GLOBAL]
+--------------------------------------PhysicalDistribute[DistributionSpecHash]
+----------------------------------------hashAgg[LOCAL]
+------------------------------------------PhysicalProject
+--------------------------------------------filter((date_dim.d_moy = 5) and 
(date_dim.d_year = 1998))
+----------------------------------------------PhysicalOlapScan[date_dim]
 ----------------------------PhysicalAssertNumRows
 ------------------------------PhysicalDistribute[DistributionSpecGather]
 --------------------------------hashAgg[GLOBAL]
@@ -61,12 +69,4 @@ PhysicalResultSink
 --------------------------------------PhysicalProject
 ----------------------------------------filter((date_dim.d_moy = 5) and 
(date_dim.d_year = 1998))
 ------------------------------------------PhysicalOlapScan[date_dim]
-------------------------PhysicalAssertNumRows
---------------------------PhysicalDistribute[DistributionSpecGather]
-----------------------------hashAgg[GLOBAL]
-------------------------------PhysicalDistribute[DistributionSpecHash]
---------------------------------hashAgg[LOCAL]
-----------------------------------PhysicalProject
-------------------------------------filter((date_dim.d_moy = 5) and 
(date_dim.d_year = 1998))
---------------------------------------PhysicalOlapScan[date_dim]
 
diff --git a/regression-test/data/shape_check/tpcds_sf100/rf_prune/query54.out 
b/regression-test/data/shape_check/tpcds_sf100/rf_prune/query54.out
index a1637bb5a33..ad8a262d794 100644
--- a/regression-test/data/shape_check/tpcds_sf100/rf_prune/query54.out
+++ b/regression-test/data/shape_check/tpcds_sf100/rf_prune/query54.out
@@ -13,50 +13,58 @@ PhysicalResultSink
 --------------------PhysicalDistribute[DistributionSpecHash]
 ----------------------hashAgg[LOCAL]
 ------------------------PhysicalProject
---------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
 ----------------------------PhysicalProject
-------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) >= d_month_seq+1)
+------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF6 c_customer_sk->[ss_customer_sk]
 --------------------------------PhysicalProject
-----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=()
+----------------------------------PhysicalOlapScan[store_sales] apply RFs: RF6 
RF7
+--------------------------------PhysicalProject
+----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF4 
s_county->[ca_county];RF5 s_state->[ca_state]
 ------------------------------------PhysicalProject
---------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF6 c_customer_sk->[ss_customer_sk]
+--------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF3 
c_current_addr_sk->[ca_address_sk]
 ----------------------------------------PhysicalProject
-------------------------------------------PhysicalOlapScan[store_sales] apply 
RFs: RF6
+------------------------------------------PhysicalOlapScan[customer_address] 
apply RFs: RF3 RF4 RF5
 ----------------------------------------PhysicalProject
-------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF4 
s_county->[ca_county];RF5 s_state->[ca_state]
---------------------------------------------PhysicalProject
-----------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF3 
c_current_addr_sk->[ca_address_sk]
-------------------------------------------------PhysicalProject
---------------------------------------------------PhysicalOlapScan[customer_address]
 apply RFs: RF3 RF4 RF5
+------------------------------------------hashAgg[GLOBAL]
+--------------------------------------------PhysicalDistribute[DistributionSpecHash]
+----------------------------------------------hashAgg[LOCAL]
 ------------------------------------------------PhysicalProject
---------------------------------------------------hashAgg[GLOBAL]
-----------------------------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------------------------hashAgg[LOCAL]
+--------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((customer.c_customer_sk = 
cs_or_ws_sales.customer_sk)) otherCondition=() build RFs:RF2 
customer_sk->[c_customer_sk]
+----------------------------------------------------PhysicalProject
+------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF2
+----------------------------------------------------PhysicalProject
+------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
 --------------------------------------------------------PhysicalProject
-----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((customer.c_customer_sk = 
cs_or_ws_sales.customer_sk)) otherCondition=() build RFs:RF2 
customer_sk->[c_customer_sk]
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF2
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------hashJoin[INNER_JOIN
 broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
+----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
+------------------------------------------------------------PhysicalUnion
+--------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------hashJoin[INNER_JOIN
 broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
---------------------------------------------------------------------PhysicalUnion
-----------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-------------------------------------------------------------------------PhysicalProject
---------------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
-----------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-------------------------------------------------------------------------PhysicalProject
---------------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
---------------------------------------------------------------------PhysicalProject
-----------------------------------------------------------------------filter((item.i_category
 = 'Women') and (item.i_class = 'maternity'))
-------------------------------------------------------------------------PhysicalOlapScan[item]
+------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
+--------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------filter((date_dim.d_moy
 = 5) and (date_dim.d_year = 1998))
---------------------------------------------------------------------PhysicalOlapScan[date_dim]
---------------------------------------------PhysicalProject
-----------------------------------------------PhysicalOlapScan[store]
+------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
+------------------------------------------------------------PhysicalProject
+--------------------------------------------------------------filter((item.i_category
 = 'Women') and (item.i_class = 'maternity'))
+----------------------------------------------------------------PhysicalOlapScan[item]
+--------------------------------------------------------PhysicalProject
+----------------------------------------------------------filter((date_dim.d_moy
 = 5) and (date_dim.d_year = 1998))
+------------------------------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalProject
+--------------------------------------PhysicalOlapScan[store]
+----------------------------PhysicalProject
+------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------------PhysicalProject
+----------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq 
as BIGINT) >= d_month_seq+1)
 ------------------------------------PhysicalProject
 --------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalAssertNumRows
+--------------------------------------PhysicalDistribute[DistributionSpecGather]
+----------------------------------------hashAgg[GLOBAL]
+------------------------------------------PhysicalDistribute[DistributionSpecHash]
+--------------------------------------------hashAgg[LOCAL]
+----------------------------------------------PhysicalProject
+------------------------------------------------filter((date_dim.d_moy = 5) 
and (date_dim.d_year = 1998))
+--------------------------------------------------PhysicalOlapScan[date_dim]
 --------------------------------PhysicalAssertNumRows
 ----------------------------------PhysicalDistribute[DistributionSpecGather]
 ------------------------------------hashAgg[GLOBAL]
@@ -65,12 +73,4 @@ PhysicalResultSink
 ------------------------------------------PhysicalProject
 --------------------------------------------filter((date_dim.d_moy = 5) and 
(date_dim.d_year = 1998))
 ----------------------------------------------PhysicalOlapScan[date_dim]
-----------------------------PhysicalAssertNumRows
-------------------------------PhysicalDistribute[DistributionSpecGather]
---------------------------------hashAgg[GLOBAL]
-----------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------hashAgg[LOCAL]
---------------------------------------PhysicalProject
-----------------------------------------filter((date_dim.d_moy = 5) and 
(date_dim.d_year = 1998))
-------------------------------------------PhysicalOlapScan[date_dim]
 
diff --git a/regression-test/data/shape_check/tpcds_sf100/shape/query54.out 
b/regression-test/data/shape_check/tpcds_sf100/shape/query54.out
index 0f6f28c79ce..ad8a262d794 100644
--- a/regression-test/data/shape_check/tpcds_sf100/shape/query54.out
+++ b/regression-test/data/shape_check/tpcds_sf100/shape/query54.out
@@ -13,50 +13,58 @@ PhysicalResultSink
 --------------------PhysicalDistribute[DistributionSpecHash]
 ----------------------hashAgg[LOCAL]
 ------------------------PhysicalProject
---------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
 ----------------------------PhysicalProject
-------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) >= d_month_seq+1)
+------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF6 c_customer_sk->[ss_customer_sk]
 --------------------------------PhysicalProject
-----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
+----------------------------------PhysicalOlapScan[store_sales] apply RFs: RF6 
RF7
+--------------------------------PhysicalProject
+----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF4 
s_county->[ca_county];RF5 s_state->[ca_state]
 ------------------------------------PhysicalProject
---------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF6 c_customer_sk->[ss_customer_sk]
+--------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF3 
c_current_addr_sk->[ca_address_sk]
 ----------------------------------------PhysicalProject
-------------------------------------------PhysicalOlapScan[store_sales] apply 
RFs: RF6 RF7
+------------------------------------------PhysicalOlapScan[customer_address] 
apply RFs: RF3 RF4 RF5
 ----------------------------------------PhysicalProject
-------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF4 
s_county->[ca_county];RF5 s_state->[ca_state]
---------------------------------------------PhysicalProject
-----------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF3 
c_current_addr_sk->[ca_address_sk]
-------------------------------------------------PhysicalProject
---------------------------------------------------PhysicalOlapScan[customer_address]
 apply RFs: RF3 RF4 RF5
+------------------------------------------hashAgg[GLOBAL]
+--------------------------------------------PhysicalDistribute[DistributionSpecHash]
+----------------------------------------------hashAgg[LOCAL]
 ------------------------------------------------PhysicalProject
---------------------------------------------------hashAgg[GLOBAL]
-----------------------------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------------------------hashAgg[LOCAL]
+--------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((customer.c_customer_sk = 
cs_or_ws_sales.customer_sk)) otherCondition=() build RFs:RF2 
customer_sk->[c_customer_sk]
+----------------------------------------------------PhysicalProject
+------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF2
+----------------------------------------------------PhysicalProject
+------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
 --------------------------------------------------------PhysicalProject
-----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((customer.c_customer_sk = 
cs_or_ws_sales.customer_sk)) otherCondition=() build RFs:RF2 
customer_sk->[c_customer_sk]
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF2
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------hashJoin[INNER_JOIN
 broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
+----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
+------------------------------------------------------------PhysicalUnion
+--------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------hashJoin[INNER_JOIN
 broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
---------------------------------------------------------------------PhysicalUnion
-----------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-------------------------------------------------------------------------PhysicalProject
---------------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
-----------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-------------------------------------------------------------------------PhysicalProject
---------------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
---------------------------------------------------------------------PhysicalProject
-----------------------------------------------------------------------filter((item.i_category
 = 'Women') and (item.i_class = 'maternity'))
-------------------------------------------------------------------------PhysicalOlapScan[item]
+------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
+--------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------filter((date_dim.d_moy
 = 5) and (date_dim.d_year = 1998))
---------------------------------------------------------------------PhysicalOlapScan[date_dim]
---------------------------------------------PhysicalProject
-----------------------------------------------PhysicalOlapScan[store]
+------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
+------------------------------------------------------------PhysicalProject
+--------------------------------------------------------------filter((item.i_category
 = 'Women') and (item.i_class = 'maternity'))
+----------------------------------------------------------------PhysicalOlapScan[item]
+--------------------------------------------------------PhysicalProject
+----------------------------------------------------------filter((date_dim.d_moy
 = 5) and (date_dim.d_year = 1998))
+------------------------------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalProject
+--------------------------------------PhysicalOlapScan[store]
+----------------------------PhysicalProject
+------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------------PhysicalProject
+----------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq 
as BIGINT) >= d_month_seq+1)
 ------------------------------------PhysicalProject
 --------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalAssertNumRows
+--------------------------------------PhysicalDistribute[DistributionSpecGather]
+----------------------------------------hashAgg[GLOBAL]
+------------------------------------------PhysicalDistribute[DistributionSpecHash]
+--------------------------------------------hashAgg[LOCAL]
+----------------------------------------------PhysicalProject
+------------------------------------------------filter((date_dim.d_moy = 5) 
and (date_dim.d_year = 1998))
+--------------------------------------------------PhysicalOlapScan[date_dim]
 --------------------------------PhysicalAssertNumRows
 ----------------------------------PhysicalDistribute[DistributionSpecGather]
 ------------------------------------hashAgg[GLOBAL]
@@ -65,12 +73,4 @@ PhysicalResultSink
 ------------------------------------------PhysicalProject
 --------------------------------------------filter((date_dim.d_moy = 5) and 
(date_dim.d_year = 1998))
 ----------------------------------------------PhysicalOlapScan[date_dim]
-----------------------------PhysicalAssertNumRows
-------------------------------PhysicalDistribute[DistributionSpecGather]
---------------------------------hashAgg[GLOBAL]
-----------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------hashAgg[LOCAL]
---------------------------------------PhysicalProject
-----------------------------------------filter((date_dim.d_moy = 5) and 
(date_dim.d_year = 1998))
-------------------------------------------PhysicalOlapScan[date_dim]
 
diff --git 
a/regression-test/data/shape_check/tpcds_sf1000/bs_downgrade_shape/query54.out 
b/regression-test/data/shape_check/tpcds_sf1000/bs_downgrade_shape/query54.out
index ba570488dc0..b7c2fe2adcd 100644
--- 
a/regression-test/data/shape_check/tpcds_sf1000/bs_downgrade_shape/query54.out
+++ 
b/regression-test/data/shape_check/tpcds_sf1000/bs_downgrade_shape/query54.out
@@ -13,50 +13,58 @@ PhysicalResultSink
 --------------------PhysicalDistribute[DistributionSpecHash]
 ----------------------hashAgg[LOCAL]
 ------------------------PhysicalProject
---------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
 ----------------------------PhysicalProject
-------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) >= d_month_seq+1)
+------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF6 c_customer_sk->[ss_customer_sk]
 --------------------------------PhysicalProject
-----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
+----------------------------------PhysicalOlapScan[store_sales] apply RFs: RF6 
RF7
+--------------------------------PhysicalProject
+----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF4 
s_county->[ca_county];RF5 s_state->[ca_state]
 ------------------------------------PhysicalProject
---------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF6 c_customer_sk->[ss_customer_sk]
+--------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF3 
c_current_addr_sk->[ca_address_sk]
 ----------------------------------------PhysicalProject
-------------------------------------------PhysicalOlapScan[store_sales] apply 
RFs: RF6 RF7
+------------------------------------------PhysicalOlapScan[customer_address] 
apply RFs: RF3 RF4 RF5
 ----------------------------------------PhysicalProject
-------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF4 
s_county->[ca_county];RF5 s_state->[ca_state]
---------------------------------------------PhysicalProject
-----------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF3 
c_current_addr_sk->[ca_address_sk]
-------------------------------------------------PhysicalProject
---------------------------------------------------PhysicalOlapScan[customer_address]
 apply RFs: RF3 RF4 RF5
+------------------------------------------hashAgg[GLOBAL]
+--------------------------------------------PhysicalDistribute[DistributionSpecHash]
+----------------------------------------------hashAgg[LOCAL]
 ------------------------------------------------PhysicalProject
---------------------------------------------------hashAgg[GLOBAL]
-----------------------------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------------------------hashAgg[LOCAL]
+--------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((customer.c_customer_sk = 
cs_or_ws_sales.customer_sk)) otherCondition=() build RFs:RF2 
customer_sk->[c_customer_sk]
+----------------------------------------------------PhysicalProject
+------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF2
+----------------------------------------------------PhysicalProject
+------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
 --------------------------------------------------------PhysicalProject
-----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((customer.c_customer_sk = 
cs_or_ws_sales.customer_sk)) otherCondition=() build RFs:RF2 
customer_sk->[c_customer_sk]
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF2
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------hashJoin[INNER_JOIN
 broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
+----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
+------------------------------------------------------------PhysicalUnion
+--------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------hashJoin[INNER_JOIN
 broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
---------------------------------------------------------------------PhysicalUnion
-----------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-------------------------------------------------------------------------PhysicalProject
---------------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
-----------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-------------------------------------------------------------------------PhysicalProject
---------------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
---------------------------------------------------------------------PhysicalProject
-----------------------------------------------------------------------filter((item.i_category
 = 'Music') and (item.i_class = 'country'))
-------------------------------------------------------------------------PhysicalOlapScan[item]
+------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
+--------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------filter((date_dim.d_moy
 = 1) and (date_dim.d_year = 1999))
---------------------------------------------------------------------PhysicalOlapScan[date_dim]
---------------------------------------------PhysicalProject
-----------------------------------------------PhysicalOlapScan[store]
+------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
+------------------------------------------------------------PhysicalProject
+--------------------------------------------------------------filter((item.i_category
 = 'Music') and (item.i_class = 'country'))
+----------------------------------------------------------------PhysicalOlapScan[item]
+--------------------------------------------------------PhysicalProject
+----------------------------------------------------------filter((date_dim.d_moy
 = 1) and (date_dim.d_year = 1999))
+------------------------------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalProject
+--------------------------------------PhysicalOlapScan[store]
+----------------------------PhysicalProject
+------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------------PhysicalProject
+----------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq 
as BIGINT) >= d_month_seq+1)
 ------------------------------------PhysicalProject
 --------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalAssertNumRows
+--------------------------------------PhysicalDistribute[DistributionSpecGather]
+----------------------------------------hashAgg[GLOBAL]
+------------------------------------------PhysicalDistribute[DistributionSpecHash]
+--------------------------------------------hashAgg[LOCAL]
+----------------------------------------------PhysicalProject
+------------------------------------------------filter((date_dim.d_moy = 1) 
and (date_dim.d_year = 1999))
+--------------------------------------------------PhysicalOlapScan[date_dim]
 --------------------------------PhysicalAssertNumRows
 ----------------------------------PhysicalDistribute[DistributionSpecGather]
 ------------------------------------hashAgg[GLOBAL]
@@ -65,12 +73,4 @@ PhysicalResultSink
 ------------------------------------------PhysicalProject
 --------------------------------------------filter((date_dim.d_moy = 1) and 
(date_dim.d_year = 1999))
 ----------------------------------------------PhysicalOlapScan[date_dim]
-----------------------------PhysicalAssertNumRows
-------------------------------PhysicalDistribute[DistributionSpecGather]
---------------------------------hashAgg[GLOBAL]
-----------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------hashAgg[LOCAL]
---------------------------------------PhysicalProject
-----------------------------------------filter((date_dim.d_moy = 1) and 
(date_dim.d_year = 1999))
-------------------------------------------PhysicalOlapScan[date_dim]
 
diff --git a/regression-test/data/shape_check/tpcds_sf1000/hint/query54.out 
b/regression-test/data/shape_check/tpcds_sf1000/hint/query54.out
index 381fcc6712e..ddc3b69f35f 100644
--- a/regression-test/data/shape_check/tpcds_sf1000/hint/query54.out
+++ b/regression-test/data/shape_check/tpcds_sf1000/hint/query54.out
@@ -13,50 +13,58 @@ PhysicalResultSink
 --------------------PhysicalDistribute[DistributionSpecHash]
 ----------------------hashAgg[LOCAL]
 ------------------------PhysicalProject
---------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
 ----------------------------PhysicalProject
-------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) >= d_month_seq+1)
+------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF6 c_customer_sk->[ss_customer_sk]
 --------------------------------PhysicalProject
-----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
+----------------------------------PhysicalOlapScan[store_sales] apply RFs: RF6 
RF7
+--------------------------------PhysicalProject
+----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF4 
s_county->[ca_county];RF5 s_state->[ca_state]
 ------------------------------------PhysicalProject
---------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF6 c_customer_sk->[ss_customer_sk]
+--------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF3 
c_current_addr_sk->[ca_address_sk]
 ----------------------------------------PhysicalProject
-------------------------------------------PhysicalOlapScan[store_sales] apply 
RFs: RF6 RF7
+------------------------------------------PhysicalOlapScan[customer_address] 
apply RFs: RF3 RF4 RF5
 ----------------------------------------PhysicalProject
-------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF4 
s_county->[ca_county];RF5 s_state->[ca_state]
---------------------------------------------PhysicalProject
-----------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF3 
c_current_addr_sk->[ca_address_sk]
-------------------------------------------------PhysicalProject
---------------------------------------------------PhysicalOlapScan[customer_address]
 apply RFs: RF3 RF4 RF5
+------------------------------------------hashAgg[GLOBAL]
+--------------------------------------------PhysicalDistribute[DistributionSpecHash]
+----------------------------------------------hashAgg[LOCAL]
 ------------------------------------------------PhysicalProject
---------------------------------------------------hashAgg[GLOBAL]
-----------------------------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------------------------hashAgg[LOCAL]
+--------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((customer.c_customer_sk = 
cs_or_ws_sales.customer_sk)) otherCondition=() build RFs:RF2 
customer_sk->[c_customer_sk]
+----------------------------------------------------PhysicalProject
+------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF2
+----------------------------------------------------PhysicalProject
+------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
 --------------------------------------------------------PhysicalProject
-----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((customer.c_customer_sk = 
cs_or_ws_sales.customer_sk)) otherCondition=() build RFs:RF2 
customer_sk->[c_customer_sk]
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF2
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------hashJoin[INNER_JOIN
 broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
+----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
+------------------------------------------------------------PhysicalUnion
+--------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------hashJoin[INNER_JOIN
 broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
---------------------------------------------------------------------PhysicalUnion
-----------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-------------------------------------------------------------------------PhysicalProject
---------------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
-----------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-------------------------------------------------------------------------PhysicalProject
---------------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
---------------------------------------------------------------------PhysicalProject
-----------------------------------------------------------------------filter((item.i_category
 = 'Music') and (item.i_class = 'country'))
-------------------------------------------------------------------------PhysicalOlapScan[item]
+------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
+--------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------filter((date_dim.d_moy
 = 1) and (date_dim.d_year = 1999))
---------------------------------------------------------------------PhysicalOlapScan[date_dim]
---------------------------------------------PhysicalProject
-----------------------------------------------PhysicalOlapScan[store]
+------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
+------------------------------------------------------------PhysicalProject
+--------------------------------------------------------------filter((item.i_category
 = 'Music') and (item.i_class = 'country'))
+----------------------------------------------------------------PhysicalOlapScan[item]
+--------------------------------------------------------PhysicalProject
+----------------------------------------------------------filter((date_dim.d_moy
 = 1) and (date_dim.d_year = 1999))
+------------------------------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalProject
+--------------------------------------PhysicalOlapScan[store]
+----------------------------PhysicalProject
+------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------------PhysicalProject
+----------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq 
as BIGINT) >= d_month_seq+1)
 ------------------------------------PhysicalProject
 --------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalAssertNumRows
+--------------------------------------PhysicalDistribute[DistributionSpecGather]
+----------------------------------------hashAgg[GLOBAL]
+------------------------------------------PhysicalDistribute[DistributionSpecHash]
+--------------------------------------------hashAgg[LOCAL]
+----------------------------------------------PhysicalProject
+------------------------------------------------filter((date_dim.d_moy = 1) 
and (date_dim.d_year = 1999))
+--------------------------------------------------PhysicalOlapScan[date_dim]
 --------------------------------PhysicalAssertNumRows
 ----------------------------------PhysicalDistribute[DistributionSpecGather]
 ------------------------------------hashAgg[GLOBAL]
@@ -65,14 +73,6 @@ PhysicalResultSink
 ------------------------------------------PhysicalProject
 --------------------------------------------filter((date_dim.d_moy = 1) and 
(date_dim.d_year = 1999))
 ----------------------------------------------PhysicalOlapScan[date_dim]
-----------------------------PhysicalAssertNumRows
-------------------------------PhysicalDistribute[DistributionSpecGather]
---------------------------------hashAgg[GLOBAL]
-----------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------hashAgg[LOCAL]
---------------------------------------PhysicalProject
-----------------------------------------filter((date_dim.d_moy = 1) and 
(date_dim.d_year = 1999))
-------------------------------------------PhysicalOlapScan[date_dim]
 
 Hint log:
 Used: leading(customer { cs_or_ws_sales item date_dim } ) leading(store_sales 
{ customer_address { my_customers store } } date_dim )
diff --git a/regression-test/data/shape_check/tpcds_sf1000/shape/query54.out 
b/regression-test/data/shape_check/tpcds_sf1000/shape/query54.out
index ba570488dc0..b7c2fe2adcd 100644
--- a/regression-test/data/shape_check/tpcds_sf1000/shape/query54.out
+++ b/regression-test/data/shape_check/tpcds_sf1000/shape/query54.out
@@ -13,50 +13,58 @@ PhysicalResultSink
 --------------------PhysicalDistribute[DistributionSpecHash]
 ----------------------hashAgg[LOCAL]
 ------------------------PhysicalProject
---------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
 ----------------------------PhysicalProject
-------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) >= d_month_seq+1)
+------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF6 c_customer_sk->[ss_customer_sk]
 --------------------------------PhysicalProject
-----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
+----------------------------------PhysicalOlapScan[store_sales] apply RFs: RF6 
RF7
+--------------------------------PhysicalProject
+----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF4 
s_county->[ca_county];RF5 s_state->[ca_state]
 ------------------------------------PhysicalProject
---------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF6 c_customer_sk->[ss_customer_sk]
+--------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF3 
c_current_addr_sk->[ca_address_sk]
 ----------------------------------------PhysicalProject
-------------------------------------------PhysicalOlapScan[store_sales] apply 
RFs: RF6 RF7
+------------------------------------------PhysicalOlapScan[customer_address] 
apply RFs: RF3 RF4 RF5
 ----------------------------------------PhysicalProject
-------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF4 
s_county->[ca_county];RF5 s_state->[ca_state]
---------------------------------------------PhysicalProject
-----------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF3 
c_current_addr_sk->[ca_address_sk]
-------------------------------------------------PhysicalProject
---------------------------------------------------PhysicalOlapScan[customer_address]
 apply RFs: RF3 RF4 RF5
+------------------------------------------hashAgg[GLOBAL]
+--------------------------------------------PhysicalDistribute[DistributionSpecHash]
+----------------------------------------------hashAgg[LOCAL]
 ------------------------------------------------PhysicalProject
---------------------------------------------------hashAgg[GLOBAL]
-----------------------------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------------------------hashAgg[LOCAL]
+--------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((customer.c_customer_sk = 
cs_or_ws_sales.customer_sk)) otherCondition=() build RFs:RF2 
customer_sk->[c_customer_sk]
+----------------------------------------------------PhysicalProject
+------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF2
+----------------------------------------------------PhysicalProject
+------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
 --------------------------------------------------------PhysicalProject
-----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((customer.c_customer_sk = 
cs_or_ws_sales.customer_sk)) otherCondition=() build RFs:RF2 
customer_sk->[c_customer_sk]
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF2
-------------------------------------------------------------PhysicalProject
---------------------------------------------------------------hashJoin[INNER_JOIN
 broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF1 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
+----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
+------------------------------------------------------------PhysicalUnion
+--------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------hashJoin[INNER_JOIN
 broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF0 i_item_sk->[cs_item_sk,ws_item_sk]
---------------------------------------------------------------------PhysicalUnion
-----------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-------------------------------------------------------------------------PhysicalProject
---------------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
-----------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
-------------------------------------------------------------------------PhysicalProject
---------------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
---------------------------------------------------------------------PhysicalProject
-----------------------------------------------------------------------filter((item.i_category
 = 'Music') and (item.i_class = 'country'))
-------------------------------------------------------------------------PhysicalOlapScan[item]
+------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1
+--------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------filter((date_dim.d_moy
 = 1) and (date_dim.d_year = 1999))
---------------------------------------------------------------------PhysicalOlapScan[date_dim]
---------------------------------------------PhysicalProject
-----------------------------------------------PhysicalOlapScan[store]
+------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1
+------------------------------------------------------------PhysicalProject
+--------------------------------------------------------------filter((item.i_category
 = 'Music') and (item.i_class = 'country'))
+----------------------------------------------------------------PhysicalOlapScan[item]
+--------------------------------------------------------PhysicalProject
+----------------------------------------------------------filter((date_dim.d_moy
 = 1) and (date_dim.d_year = 1999))
+------------------------------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalProject
+--------------------------------------PhysicalOlapScan[store]
+----------------------------PhysicalProject
+------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------------PhysicalProject
+----------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq 
as BIGINT) >= d_month_seq+1)
 ------------------------------------PhysicalProject
 --------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalAssertNumRows
+--------------------------------------PhysicalDistribute[DistributionSpecGather]
+----------------------------------------hashAgg[GLOBAL]
+------------------------------------------PhysicalDistribute[DistributionSpecHash]
+--------------------------------------------hashAgg[LOCAL]
+----------------------------------------------PhysicalProject
+------------------------------------------------filter((date_dim.d_moy = 1) 
and (date_dim.d_year = 1999))
+--------------------------------------------------PhysicalOlapScan[date_dim]
 --------------------------------PhysicalAssertNumRows
 ----------------------------------PhysicalDistribute[DistributionSpecGather]
 ------------------------------------hashAgg[GLOBAL]
@@ -65,12 +73,4 @@ PhysicalResultSink
 ------------------------------------------PhysicalProject
 --------------------------------------------filter((date_dim.d_moy = 1) and 
(date_dim.d_year = 1999))
 ----------------------------------------------PhysicalOlapScan[date_dim]
-----------------------------PhysicalAssertNumRows
-------------------------------PhysicalDistribute[DistributionSpecGather]
---------------------------------hashAgg[GLOBAL]
-----------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------hashAgg[LOCAL]
---------------------------------------PhysicalProject
-----------------------------------------filter((date_dim.d_moy = 1) and 
(date_dim.d_year = 1999))
-------------------------------------------PhysicalOlapScan[date_dim]
 
diff --git a/regression-test/data/shape_check/tpcds_sf10t_orc/shape/query54.out 
b/regression-test/data/shape_check/tpcds_sf10t_orc/shape/query54.out
index 3bf22e26771..6d88dce347d 100644
--- a/regression-test/data/shape_check/tpcds_sf10t_orc/shape/query54.out
+++ b/regression-test/data/shape_check/tpcds_sf10t_orc/shape/query54.out
@@ -13,48 +13,56 @@ PhysicalResultSink
 --------------------PhysicalDistribute[DistributionSpecHash]
 ----------------------hashAgg[LOCAL]
 ------------------------PhysicalProject
---------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
 ----------------------------PhysicalProject
-------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) >= d_month_seq+1)
+------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF5 
s_county->[ca_county];RF6 s_state->[ca_state]
 --------------------------------PhysicalProject
-----------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((store_sales.ss_sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF7 d_date_sk->[ss_sold_date_sk]
+----------------------------------hashJoin[INNER_JOIN shuffle] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF4 
ca_address_sk->[c_current_addr_sk]
 ------------------------------------PhysicalProject
---------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((customer_address.ca_county = store.s_county) and 
(customer_address.ca_state = store.s_state)) otherCondition=() build RFs:RF5 
s_county->[ca_county];RF6 s_state->[ca_state]
+--------------------------------------hashJoin[INNER_JOIN shuffle] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF3 c_customer_sk->[ss_customer_sk]
 ----------------------------------------PhysicalProject
-------------------------------------------hashJoin[INNER_JOIN shuffle] 
hashCondition=((my_customers.c_current_addr_sk = 
customer_address.ca_address_sk)) otherCondition=() build RFs:RF4 
ca_address_sk->[c_current_addr_sk]
+------------------------------------------PhysicalOlapScan[store_sales] apply 
RFs: RF3 RF7
+----------------------------------------PhysicalProject
+------------------------------------------hashAgg[GLOBAL]
 --------------------------------------------PhysicalProject
-----------------------------------------------hashJoin[INNER_JOIN shuffle] 
hashCondition=((my_customers.c_customer_sk = store_sales.ss_customer_sk)) 
otherCondition=() build RFs:RF3 c_customer_sk->[ss_customer_sk]
-------------------------------------------------PhysicalProject
---------------------------------------------------PhysicalOlapScan[store_sales]
 apply RFs: RF3 RF7
+----------------------------------------------hashJoin[INNER_JOIN broadcast] 
hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF2 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
 ------------------------------------------------PhysicalProject
---------------------------------------------------hashAgg[GLOBAL]
+--------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF1 i_item_sk->[cs_item_sk,ws_item_sk]
 ----------------------------------------------------PhysicalProject
-------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.sold_date_sk = date_dim.d_date_sk)) 
otherCondition=() build RFs:RF2 d_date_sk->[cs_sold_date_sk,ws_sold_date_sk]
---------------------------------------------------------PhysicalProject
-----------------------------------------------------------hashJoin[INNER_JOIN 
broadcast] hashCondition=((cs_or_ws_sales.item_sk = item.i_item_sk)) 
otherCondition=() build RFs:RF1 i_item_sk->[cs_item_sk,ws_item_sk]
+------------------------------------------------------hashJoin[INNER_JOIN 
shuffle] hashCondition=((customer.c_customer_sk = cs_or_ws_sales.customer_sk)) 
otherCondition=() build RFs:RF0 
c_customer_sk->[cs_bill_customer_sk,ws_bill_customer_sk]
+--------------------------------------------------------PhysicalUnion
+----------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ------------------------------------------------------------PhysicalProject
---------------------------------------------------------------hashJoin[INNER_JOIN
 shuffle] hashCondition=((customer.c_customer_sk = cs_or_ws_sales.customer_sk)) 
otherCondition=() build RFs:RF0 
c_customer_sk->[cs_bill_customer_sk,ws_bill_customer_sk]
-----------------------------------------------------------------PhysicalUnion
-------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
---------------------------------------------------------------------PhysicalProject
-----------------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1 RF2
-------------------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
---------------------------------------------------------------------PhysicalProject
-----------------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1 RF2
-----------------------------------------------------------------PhysicalProject
-------------------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF4
+--------------------------------------------------------------PhysicalOlapScan[catalog_sales]
 apply RFs: RF0 RF1 RF2
+----------------------------------------------------------PhysicalDistribute[DistributionSpecExecutionAny]
 ------------------------------------------------------------PhysicalProject
---------------------------------------------------------------filter((item.i_category
 = 'Books') and (item.i_class = 'business'))
-----------------------------------------------------------------PhysicalOlapScan[item]
+--------------------------------------------------------------PhysicalOlapScan[web_sales]
 apply RFs: RF0 RF1 RF2
 --------------------------------------------------------PhysicalProject
-----------------------------------------------------------filter((date_dim.d_moy
 = 2) and (date_dim.d_year = 2000))
-------------------------------------------------------------PhysicalOlapScan[date_dim]
---------------------------------------------PhysicalProject
-----------------------------------------------PhysicalOlapScan[customer_address]
 apply RFs: RF5 RF6
-----------------------------------------PhysicalProject
-------------------------------------------PhysicalOlapScan[store]
+----------------------------------------------------------PhysicalOlapScan[customer]
 apply RFs: RF4
+----------------------------------------------------PhysicalProject
+------------------------------------------------------filter((item.i_category 
= 'Books') and (item.i_class = 'business'))
+--------------------------------------------------------PhysicalOlapScan[item]
+------------------------------------------------PhysicalProject
+--------------------------------------------------filter((date_dim.d_moy = 2) 
and (date_dim.d_year = 2000))
+----------------------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalProject
+--------------------------------------PhysicalOlapScan[customer_address] apply 
RFs: RF5 RF6
+--------------------------------PhysicalProject
+----------------------------------PhysicalOlapScan[store]
+----------------------------PhysicalProject
+------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq as 
BIGINT) <= d_month_seq+3)
+--------------------------------PhysicalProject
+----------------------------------NestedLoopJoin[INNER_JOIN](cast(d_month_seq 
as BIGINT) >= d_month_seq+1)
 ------------------------------------PhysicalProject
 --------------------------------------PhysicalOlapScan[date_dim]
+------------------------------------PhysicalAssertNumRows
+--------------------------------------PhysicalDistribute[DistributionSpecGather]
+----------------------------------------hashAgg[GLOBAL]
+------------------------------------------PhysicalDistribute[DistributionSpecHash]
+--------------------------------------------hashAgg[LOCAL]
+----------------------------------------------PhysicalProject
+------------------------------------------------filter((date_dim.d_moy = 2) 
and (date_dim.d_year = 2000))
+--------------------------------------------------PhysicalOlapScan[date_dim]
 --------------------------------PhysicalAssertNumRows
 ----------------------------------PhysicalDistribute[DistributionSpecGather]
 ------------------------------------hashAgg[GLOBAL]
@@ -63,12 +71,4 @@ PhysicalResultSink
 ------------------------------------------PhysicalProject
 --------------------------------------------filter((date_dim.d_moy = 2) and 
(date_dim.d_year = 2000))
 ----------------------------------------------PhysicalOlapScan[date_dim]
-----------------------------PhysicalAssertNumRows
-------------------------------PhysicalDistribute[DistributionSpecGather]
---------------------------------hashAgg[GLOBAL]
-----------------------------------PhysicalDistribute[DistributionSpecHash]
-------------------------------------hashAgg[LOCAL]
---------------------------------------PhysicalProject
-----------------------------------------filter((date_dim.d_moy = 2) and 
(date_dim.d_year = 2000))
-------------------------------------------PhysicalOlapScan[date_dim]
 


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

Reply via email to