You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by zh...@apache.org on 2023/01/30 08:42:07 UTC

[flink] branch master updated (5afc301bc64 -> 143464d8281)

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

zhuzh pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git


    from 5afc301bc64 [FLINK-30665][table] Planner supports row-level update
     new 11a0fc32c9c [hotfix] Migrate ExecutionConfigTest to JUnit5.
     new 1bfde8119d2 [hotfix][runtime] remove ExecutionConfig#setScheduler
     new 143464d8281 [FLINK-30683][runtime] Use AdaptiveBatchScheduler as default batch scheduler

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../explain/testCountAggFunctionFallbackPlan.out   |  27 +-
 .../explain/testMaxAggFunctionFallbackPlan.out     |  12 +-
 .../explain/testMinAggFunctionFallbackPlan.out     |  12 +-
 .../explain/testSumAggFunctionFallbackPlan.out     |  12 +-
 .../apache/flink/api/common/ExecutionConfig.java   |  21 +-
 .../flink/api/common/ExecutionConfigTest.java      | 124 ++-
 .../optimizer/plantranslate/JobGraphGenerator.java |  13 +-
 .../JobMasterServiceLeadershipRunnerFactory.java   |   2 +-
 .../apache/flink/runtime/jobgraph/JobGraph.java    |  10 +
 .../DefaultSlotPoolServiceSchedulerFactory.java    |  23 +-
 ...DefaultSlotPoolServiceSchedulerFactoryTest.java |   4 +-
 .../flink/runtime/jobmaster/JobMasterTest.java     |  11 +-
 .../runtime/jobmaster/utils/JobMasterBuilder.java  |   2 +-
 .../adaptivebatch/AdaptiveBatchSchedulerTest.java  |  11 -
 .../flink/streaming/api/graph/StreamGraph.java     |  14 +-
 .../streaming/api/graph/StreamGraphGenerator.java  |  11 +
 .../api/graph/StreamingJobGraphGenerator.java      |  11 +-
 .../partitioner/StreamPartitionerTestUtils.java    |   3 -
 .../processor/ForwardHashExchangeProcessor.java    |   9 +-
 .../plan/batch/sql/ForwardHashExchangeTest.java    |   2 -
 .../runtime/batch/ParallelismSettingTest.java      |   1 -
 .../runtime/batch/sql/DynamicFilteringITCase.java  |  30 +-
 .../batch/sql/ForwardHashExchangeITCase.java       |   2 -
 .../batch/sql/join/AdaptiveHashJoinITCase.java     |   4 -
 .../planner/plan/batch/sql/DagOptimizationTest.xml |  16 +-
 .../planner/plan/batch/sql/DeadlockBreakupTest.xml |  76 +-
 .../plan/batch/sql/MultipleInputCreationTest.xml   | 867 +++++++++++++++++++--
 .../table/planner/plan/batch/sql/RankTest.xml      | 136 ++--
 .../planner/plan/batch/sql/RemoveCollationTest.xml | 199 +++--
 .../planner/plan/batch/sql/RemoveShuffleTest.xml   | 253 +++---
 .../planner/plan/batch/sql/SetOperatorsTest.xml    |  56 +-
 .../planner/plan/batch/sql/SubplanReuseTest.xml    |  81 +-
 .../table/planner/plan/batch/sql/UnnestTest.xml    |  42 +-
 .../plan/batch/sql/WindowTableFunctionTest.xml     |  50 +-
 .../batch/sql/agg/AggregateReduceGroupingTest.xml  | 122 +--
 .../plan/batch/sql/agg/DistinctAggregateTest.xml   |  48 +-
 .../planner/plan/batch/sql/agg/GroupWindowTest.xml | 192 +++--
 .../plan/batch/sql/agg/GroupingSetsTest.xml        |  24 +-
 .../plan/batch/sql/agg/OverAggregateTest.xml       | 268 ++++---
 .../plan/batch/sql/agg/SortAggregateTest.xml       | 196 +++--
 .../sql/join/BroadcastHashSemiAntiJoinTest.xml     |  20 +-
 .../planner/plan/batch/sql/join/LookupJoinTest.xml |   4 +-
 .../batch/sql/join/NestedLoopSemiAntiJoinTest.xml  |  20 +-
 .../plan/batch/sql/join/SemiAntiJoinTest.xml       |  20 +-
 .../sql/join/ShuffledHashSemiAntiJoinTest.xml      |  20 +-
 .../plan/batch/sql/join/SingleRowJoinTest.xml      |  26 +-
 .../batch/sql/join/SortMergeSemiAntiJoinTest.xml   |  53 +-
 .../planner/plan/batch/table/GroupWindowTest.xml   |  13 +-
 .../plan/batch/table/PythonAggregateTest.xml       |   7 +-
 .../batch/table/PythonGroupWindowAggregateTest.xml |  14 +-
 .../batch/table/PythonOverWindowAggregateTest.xml  |  14 +-
 .../planner/plan/batch/table/SetOperatorsTest.xml  |   2 +-
 .../nodes/exec/operator/BatchOperatorNameTest.xml  |  86 +-
 .../plan/batch/sql/DeadlockBreakupTest.scala       |   4 +
 .../plan/batch/sql/MultipleInputCreationTest.scala |  18 +-
 .../runtime/batch/sql/MultipleInputITCase.scala    |  18 +-
 .../planner/runtime/utils/BatchTestBase.scala      |   3 -
 .../flink/table/planner/utils/TableTestBase.scala  |   4 -
 .../scheduling/AdaptiveBatchSchedulerITCase.java   |   2 -
 .../PipelinedRegionSchedulingITCase.java           |   1 +
 .../scheduling/SpeculativeSchedulerITCase.java     |   2 -
 61 files changed, 2212 insertions(+), 1136 deletions(-)


[flink] 03/03: [FLINK-30683][runtime] Use AdaptiveBatchScheduler as default batch scheduler

Posted by zh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zhuzh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git

commit 143464d82814e342aa845f3ac976ae2854fc892f
Author: JunRuiLee <jr...@gmail.com>
AuthorDate: Mon Jan 16 12:10:03 2023 +0800

    [FLINK-30683][runtime] Use AdaptiveBatchScheduler as default batch scheduler
    
    This closes #21672.
---
 .../explain/testCountAggFunctionFallbackPlan.out   |  27 +-
 .../explain/testMaxAggFunctionFallbackPlan.out     |  12 +-
 .../explain/testMinAggFunctionFallbackPlan.out     |  12 +-
 .../explain/testSumAggFunctionFallbackPlan.out     |  12 +-
 .../apache/flink/api/common/ExecutionConfig.java   |   5 +-
 .../flink/api/common/ExecutionConfigTest.java      |  15 +-
 .../optimizer/plantranslate/JobGraphGenerator.java |  13 +-
 .../JobMasterServiceLeadershipRunnerFactory.java   |   2 +-
 .../apache/flink/runtime/jobgraph/JobGraph.java    |  10 +
 .../DefaultSlotPoolServiceSchedulerFactory.java    |  23 +-
 ...DefaultSlotPoolServiceSchedulerFactoryTest.java |   4 +-
 .../flink/runtime/jobmaster/JobMasterTest.java     |  11 +-
 .../runtime/jobmaster/utils/JobMasterBuilder.java  |   2 +-
 .../adaptivebatch/AdaptiveBatchSchedulerTest.java  |  11 -
 .../flink/streaming/api/graph/StreamGraph.java     |  14 +-
 .../streaming/api/graph/StreamGraphGenerator.java  |  11 +
 .../api/graph/StreamingJobGraphGenerator.java      |  11 +-
 .../partitioner/StreamPartitionerTestUtils.java    |   3 -
 .../processor/ForwardHashExchangeProcessor.java    |   9 +-
 .../runtime/batch/sql/DynamicFilteringITCase.java  |  30 +-
 .../batch/sql/join/AdaptiveHashJoinITCase.java     |   4 -
 .../planner/plan/batch/sql/DagOptimizationTest.xml |  16 +-
 .../planner/plan/batch/sql/DeadlockBreakupTest.xml |  76 +-
 .../plan/batch/sql/MultipleInputCreationTest.xml   | 867 +++++++++++++++++++--
 .../table/planner/plan/batch/sql/RankTest.xml      | 136 ++--
 .../planner/plan/batch/sql/RemoveCollationTest.xml | 199 +++--
 .../planner/plan/batch/sql/RemoveShuffleTest.xml   | 253 +++---
 .../planner/plan/batch/sql/SetOperatorsTest.xml    |  56 +-
 .../planner/plan/batch/sql/SubplanReuseTest.xml    |  81 +-
 .../table/planner/plan/batch/sql/UnnestTest.xml    |  42 +-
 .../plan/batch/sql/WindowTableFunctionTest.xml     |  50 +-
 .../batch/sql/agg/AggregateReduceGroupingTest.xml  | 122 +--
 .../plan/batch/sql/agg/DistinctAggregateTest.xml   |  48 +-
 .../planner/plan/batch/sql/agg/GroupWindowTest.xml | 192 +++--
 .../plan/batch/sql/agg/GroupingSetsTest.xml        |  24 +-
 .../plan/batch/sql/agg/OverAggregateTest.xml       | 268 ++++---
 .../plan/batch/sql/agg/SortAggregateTest.xml       | 196 +++--
 .../sql/join/BroadcastHashSemiAntiJoinTest.xml     |  20 +-
 .../planner/plan/batch/sql/join/LookupJoinTest.xml |   4 +-
 .../batch/sql/join/NestedLoopSemiAntiJoinTest.xml  |  20 +-
 .../plan/batch/sql/join/SemiAntiJoinTest.xml       |  20 +-
 .../sql/join/ShuffledHashSemiAntiJoinTest.xml      |  20 +-
 .../plan/batch/sql/join/SingleRowJoinTest.xml      |  26 +-
 .../batch/sql/join/SortMergeSemiAntiJoinTest.xml   |  53 +-
 .../planner/plan/batch/table/GroupWindowTest.xml   |  13 +-
 .../plan/batch/table/PythonAggregateTest.xml       |   7 +-
 .../batch/table/PythonGroupWindowAggregateTest.xml |  14 +-
 .../batch/table/PythonOverWindowAggregateTest.xml  |  14 +-
 .../planner/plan/batch/table/SetOperatorsTest.xml  |   2 +-
 .../nodes/exec/operator/BatchOperatorNameTest.xml  |  86 +-
 .../plan/batch/sql/DeadlockBreakupTest.scala       |   4 +
 .../plan/batch/sql/MultipleInputCreationTest.scala |  18 +-
 .../runtime/batch/sql/MultipleInputITCase.scala    |  18 +-
 .../planner/runtime/utils/BatchTestBase.scala      |   3 -
 .../flink/table/planner/utils/TableTestBase.scala  |   4 -
 .../scheduling/AdaptiveBatchSchedulerITCase.java   |   2 -
 .../PipelinedRegionSchedulingITCase.java           |   1 +
 .../scheduling/SpeculativeSchedulerITCase.java     |   2 -
 58 files changed, 2159 insertions(+), 1059 deletions(-)

diff --git a/flink-connectors/flink-connector-hive/src/test/resources/explain/testCountAggFunctionFallbackPlan.out b/flink-connectors/flink-connector-hive/src/test/resources/explain/testCountAggFunctionFallbackPlan.out
index e356f402212..4bfda1d9191 100644
--- a/flink-connectors/flink-connector-hive/src/test/resources/explain/testCountAggFunctionFallbackPlan.out
+++ b/flink-connectors/flink-connector-hive/src/test/resources/explain/testCountAggFunctionFallbackPlan.out
@@ -21,15 +21,18 @@ SortAggregate(isMerge=[true], groupBy=[x], select=[x, Final_MIN(min$0) AS $f1, F
 
 == Optimized Execution Plan ==
 SortAggregate(isMerge=[true], groupBy=[x], select=[x, Final_MIN(min$0) AS $f1, Final_MIN(min$1) AS $f2, Final_count($f3) AS $f3])
-+- Sort(orderBy=[x ASC])
-   +- Exchange(distribution=[hash[x]])
-      +- LocalSortAggregate(groupBy=[x], select=[x, Partial_MIN($f1) FILTER $g_1 AS min$0, Partial_MIN($f2) FILTER $g_1 AS min$1, Partial_count(y) FILTER $g_0 AS $f3])
-         +- Calc(select=[x, y, $f1, $f2, (CASE(($e = 0), 0, 1) = 0) AS $g_0, (CASE(($e = 0), 0, 1) = 1) AS $g_1])
-            +- Sort(orderBy=[x ASC])
-               +- SortAggregate(isMerge=[true], groupBy=[x, y, $e], select=[x, y, $e, Final_count($f1) AS $f1, Final_count($f2) AS $f2])
-                  +- Sort(orderBy=[x ASC, y ASC, $e ASC])
-                     +- Exchange(distribution=[hash[x, y, $e]])
-                        +- LocalSortAggregate(groupBy=[x, y, $e], select=[x, y, $e, Partial_count(*) AS $f1, Partial_count(y_0) AS $f2])
-                           +- Sort(orderBy=[x ASC, y ASC, $e ASC])
-                              +- Expand(projects=[{x, y, 0 AS $e, y AS y_0}, {x, null AS y, 1 AS $e, y AS y_0}])
-                                 +- TableSourceScan(table=[[test-catalog, default, foo]], fields=[x, y])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[x ASC])
+      +- Exchange(distribution=[hash[x]])
+         +- LocalSortAggregate(groupBy=[x], select=[x, Partial_MIN($f1) FILTER $g_1 AS min$0, Partial_MIN($f2) FILTER $g_1 AS min$1, Partial_count(y) FILTER $g_0 AS $f3])
+            +- Calc(select=[x, y, $f1, $f2, (CASE(($e = 0), 0, 1) = 0) AS $g_0, (CASE(($e = 0), 0, 1) = 1) AS $g_1])
+               +- Sort(orderBy=[x ASC])
+                  +- SortAggregate(isMerge=[true], groupBy=[x, y, $e], select=[x, y, $e, Final_count($f1) AS $f1, Final_count($f2) AS $f2])
+                     +- Exchange(distribution=[forward])
+                        +- Sort(orderBy=[x ASC, y ASC, $e ASC])
+                           +- Exchange(distribution=[hash[x, y, $e]])
+                              +- LocalSortAggregate(groupBy=[x, y, $e], select=[x, y, $e, Partial_count(*) AS $f1, Partial_count(y_0) AS $f2])
+                                 +- Exchange(distribution=[forward])
+                                    +- Sort(orderBy=[x ASC, y ASC, $e ASC])
+                                       +- Expand(projects=[{x, y, 0 AS $e, y AS y_0}, {x, null AS y, 1 AS $e, y AS y_0}])
+                                          +- TableSourceScan(table=[[test-catalog, default, foo]], fields=[x, y])
diff --git a/flink-connectors/flink-connector-hive/src/test/resources/explain/testMaxAggFunctionFallbackPlan.out b/flink-connectors/flink-connector-hive/src/test/resources/explain/testMaxAggFunctionFallbackPlan.out
index e25fa76f0e0..4352770b764 100644
--- a/flink-connectors/flink-connector-hive/src/test/resources/explain/testMaxAggFunctionFallbackPlan.out
+++ b/flink-connectors/flink-connector-hive/src/test/resources/explain/testMaxAggFunctionFallbackPlan.out
@@ -14,8 +14,10 @@ SortAggregate(isMerge=[true], groupBy=[x], select=[x, Final_max($f1) AS $f1])
 
 == Optimized Execution Plan ==
 SortAggregate(isMerge=[true], groupBy=[x], select=[x, Final_max($f1) AS $f1])
-+- Sort(orderBy=[x ASC])
-   +- Exchange(distribution=[hash[x]])
-      +- LocalSortAggregate(groupBy=[x], select=[x, Partial_max(y) AS $f1])
-         +- Sort(orderBy=[x ASC])
-            +- TableSourceScan(table=[[test-catalog, default, foo]], fields=[x, y])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[x ASC])
+      +- Exchange(distribution=[hash[x]])
+         +- LocalSortAggregate(groupBy=[x], select=[x, Partial_max(y) AS $f1])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[x ASC])
+                  +- TableSourceScan(table=[[test-catalog, default, foo]], fields=[x, y])
diff --git a/flink-connectors/flink-connector-hive/src/test/resources/explain/testMinAggFunctionFallbackPlan.out b/flink-connectors/flink-connector-hive/src/test/resources/explain/testMinAggFunctionFallbackPlan.out
index 1dc2488ba8f..1ba92eba83e 100644
--- a/flink-connectors/flink-connector-hive/src/test/resources/explain/testMinAggFunctionFallbackPlan.out
+++ b/flink-connectors/flink-connector-hive/src/test/resources/explain/testMinAggFunctionFallbackPlan.out
@@ -14,8 +14,10 @@ SortAggregate(isMerge=[true], groupBy=[x], select=[x, Final_min($f1) AS $f1])
 
 == Optimized Execution Plan ==
 SortAggregate(isMerge=[true], groupBy=[x], select=[x, Final_min($f1) AS $f1])
-+- Sort(orderBy=[x ASC])
-   +- Exchange(distribution=[hash[x]])
-      +- LocalSortAggregate(groupBy=[x], select=[x, Partial_min(y) AS $f1])
-         +- Sort(orderBy=[x ASC])
-            +- TableSourceScan(table=[[test-catalog, default, foo]], fields=[x, y])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[x ASC])
+      +- Exchange(distribution=[hash[x]])
+         +- LocalSortAggregate(groupBy=[x], select=[x, Partial_min(y) AS $f1])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[x ASC])
+                  +- TableSourceScan(table=[[test-catalog, default, foo]], fields=[x, y])
diff --git a/flink-connectors/flink-connector-hive/src/test/resources/explain/testSumAggFunctionFallbackPlan.out b/flink-connectors/flink-connector-hive/src/test/resources/explain/testSumAggFunctionFallbackPlan.out
index e297c060e46..14d18c19afc 100644
--- a/flink-connectors/flink-connector-hive/src/test/resources/explain/testSumAggFunctionFallbackPlan.out
+++ b/flink-connectors/flink-connector-hive/src/test/resources/explain/testSumAggFunctionFallbackPlan.out
@@ -14,8 +14,10 @@ SortAggregate(isMerge=[true], groupBy=[x], select=[x, Final_sum($f1) AS $f1])
 
 == Optimized Execution Plan ==
 SortAggregate(isMerge=[true], groupBy=[x], select=[x, Final_sum($f1) AS $f1])
-+- Sort(orderBy=[x ASC])
-   +- Exchange(distribution=[hash[x]])
-      +- LocalSortAggregate(groupBy=[x], select=[x, Partial_sum(y) AS $f1])
-         +- Sort(orderBy=[x ASC])
-            +- TableSourceScan(table=[[test-catalog, default, foo]], fields=[x, y])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[x ASC])
+      +- Exchange(distribution=[hash[x]])
+         +- LocalSortAggregate(groupBy=[x], select=[x, Partial_sum(y) AS $f1])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[x ASC])
+                  +- TableSourceScan(table=[[test-catalog, default, foo]], fields=[x, y])
diff --git a/flink-core/src/main/java/org/apache/flink/api/common/ExecutionConfig.java b/flink-core/src/main/java/org/apache/flink/api/common/ExecutionConfig.java
index f5e027a1939..e09cd74a8a8 100644
--- a/flink-core/src/main/java/org/apache/flink/api/common/ExecutionConfig.java
+++ b/flink-core/src/main/java/org/apache/flink/api/common/ExecutionConfig.java
@@ -48,6 +48,7 @@ import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 import static org.apache.flink.configuration.ConfigOptions.key;
@@ -469,8 +470,8 @@ public class ExecutionConfig implements Serializable, Archiveable<ArchivedExecut
     }
 
     @Internal
-    public boolean isDynamicGraph() {
-        return configuration.get(JobManagerOptions.SCHEDULER) == SchedulerType.AdaptiveBatch;
+    public Optional<SchedulerType> getSchedulerType() {
+        return configuration.getOptional(JobManagerOptions.SCHEDULER);
     }
 
     /**
diff --git a/flink-core/src/test/java/org/apache/flink/api/common/ExecutionConfigTest.java b/flink-core/src/test/java/org/apache/flink/api/common/ExecutionConfigTest.java
index 91786802cf4..04bccafc4e7 100644
--- a/flink-core/src/test/java/org/apache/flink/api/common/ExecutionConfigTest.java
+++ b/flink-core/src/test/java/org/apache/flink/api/common/ExecutionConfigTest.java
@@ -273,15 +273,14 @@ public class ExecutionConfigTest {
     }
 
     @Test
-    public void testLoadingIsDynamicGraphFromConfiguration() {
-        testLoadingIsDynamicGraphFromConfiguration(
-                JobManagerOptions.SchedulerType.AdaptiveBatch, true);
-        testLoadingIsDynamicGraphFromConfiguration(JobManagerOptions.SchedulerType.Default, false);
-        testLoadingIsDynamicGraphFromConfiguration(JobManagerOptions.SchedulerType.Adaptive, false);
+    public void testLoadingSchedulerTypeFromConfiguration() {
+        testLoadingSchedulerTypeFromConfiguration(JobManagerOptions.SchedulerType.AdaptiveBatch);
+        testLoadingSchedulerTypeFromConfiguration(JobManagerOptions.SchedulerType.Default);
+        testLoadingSchedulerTypeFromConfiguration(JobManagerOptions.SchedulerType.Adaptive);
     }
 
-    private void testLoadingIsDynamicGraphFromConfiguration(
-            JobManagerOptions.SchedulerType schedulerType, boolean expectIsDynamicGraph) {
+    private void testLoadingSchedulerTypeFromConfiguration(
+            JobManagerOptions.SchedulerType schedulerType) {
         Configuration configuration = new Configuration();
         configuration.set(JobManagerOptions.SCHEDULER, schedulerType);
 
@@ -289,7 +288,7 @@ public class ExecutionConfigTest {
         configFromConfiguration.configure(
                 configuration, Thread.currentThread().getContextClassLoader());
 
-        assertThat(configFromConfiguration.isDynamicGraph()).isEqualTo(expectIsDynamicGraph);
+        assertThat(configFromConfiguration.getSchedulerType().get()).isEqualTo(schedulerType);
     }
 
     @Test
diff --git a/flink-optimizer/src/main/java/org/apache/flink/optimizer/plantranslate/JobGraphGenerator.java b/flink-optimizer/src/main/java/org/apache/flink/optimizer/plantranslate/JobGraphGenerator.java
index 887da47ed0c..30fd165e2e7 100644
--- a/flink-optimizer/src/main/java/org/apache/flink/optimizer/plantranslate/JobGraphGenerator.java
+++ b/flink-optimizer/src/main/java/org/apache/flink/optimizer/plantranslate/JobGraphGenerator.java
@@ -18,6 +18,7 @@
 
 package org.apache.flink.optimizer.plantranslate;
 
+import org.apache.flink.api.common.ExecutionConfig;
 import org.apache.flink.api.common.JobID;
 import org.apache.flink.api.common.aggregators.AggregatorRegistry;
 import org.apache.flink.api.common.aggregators.AggregatorWithName;
@@ -34,6 +35,7 @@ import org.apache.flink.configuration.AlgorithmOptions;
 import org.apache.flink.configuration.ConfigConstants;
 import org.apache.flink.configuration.Configuration;
 import org.apache.flink.configuration.GlobalConfiguration;
+import org.apache.flink.configuration.JobManagerOptions;
 import org.apache.flink.optimizer.CompilerException;
 import org.apache.flink.optimizer.dag.TempMode;
 import org.apache.flink.optimizer.plan.BulkIterationPlanNode;
@@ -211,6 +213,8 @@ public class JobGraphGenerator implements Visitor<PlanNode> {
 
         this.sharingGroup = new SlotSharingGroup();
 
+        ExecutionConfig executionConfig = program.getOriginalPlan().getExecutionConfig();
+
         // this starts the traversal that generates the job graph
         program.accept(this);
 
@@ -261,11 +265,18 @@ public class JobGraphGenerator implements Visitor<PlanNode> {
                     JobGraphBuilder.newBatchJobGraphBuilder()
                             .setJobId(jobId)
                             .setJobName(program.getJobName())
-                            .setExecutionConfig(program.getOriginalPlan().getExecutionConfig())
+                            .setExecutionConfig(executionConfig)
                             .addJobVertices(vertices.values())
                             .addJobVertices(auxVertices)
                             .addUserArtifacts(userArtifacts)
                             .build();
+
+            if (executionConfig.getSchedulerType().isPresent()
+                    && executionConfig.getSchedulerType().get()
+                            == JobManagerOptions.SchedulerType.AdaptiveBatch) {
+                graph.setDynamic(true);
+            }
+
         } catch (IOException e) {
             throw new CompilerException(
                     "Could not serialize the ExecutionConfig."
diff --git a/flink-runtime/src/main/java/org/apache/flink/runtime/dispatcher/JobMasterServiceLeadershipRunnerFactory.java b/flink-runtime/src/main/java/org/apache/flink/runtime/dispatcher/JobMasterServiceLeadershipRunnerFactory.java
index e670f2d0cdd..3b9e8db13f8 100644
--- a/flink-runtime/src/main/java/org/apache/flink/runtime/dispatcher/JobMasterServiceLeadershipRunnerFactory.java
+++ b/flink-runtime/src/main/java/org/apache/flink/runtime/dispatcher/JobMasterServiceLeadershipRunnerFactory.java
@@ -71,7 +71,7 @@ public enum JobMasterServiceLeadershipRunnerFactory implements JobManagerRunnerF
 
         final SlotPoolServiceSchedulerFactory slotPoolServiceSchedulerFactory =
                 DefaultSlotPoolServiceSchedulerFactory.fromConfiguration(
-                        configuration, jobGraph.getJobType());
+                        configuration, jobGraph.getJobType(), jobGraph.isDynamic());
 
         if (jobMasterConfiguration.getConfiguration().get(JobManagerOptions.SCHEDULER_MODE)
                 == SchedulerExecutionMode.REACTIVE) {
diff --git a/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/JobGraph.java b/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/JobGraph.java
index 7a739a40289..14e49c89228 100644
--- a/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/JobGraph.java
+++ b/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/JobGraph.java
@@ -89,6 +89,8 @@ public class JobGraph implements Serializable {
 
     private JobType jobType = JobType.BATCH;
 
+    private boolean dynamic;
+
     /**
      * Whether approximate local recovery is enabled. This flag will be removed together with legacy
      * scheduling strategies.
@@ -225,6 +227,14 @@ public class JobGraph implements Serializable {
         return jobType;
     }
 
+    public void setDynamic(boolean dynamic) {
+        this.dynamic = dynamic;
+    }
+
+    public boolean isDynamic() {
+        return dynamic;
+    }
+
     public void enableApproximateLocalRecovery(boolean enabled) {
         this.approximateLocalRecovery = enabled;
     }
diff --git a/flink-runtime/src/main/java/org/apache/flink/runtime/jobmaster/DefaultSlotPoolServiceSchedulerFactory.java b/flink-runtime/src/main/java/org/apache/flink/runtime/jobmaster/DefaultSlotPoolServiceSchedulerFactory.java
index b99039ccc4f..bc05dd8f685 100644
--- a/flink-runtime/src/main/java/org/apache/flink/runtime/jobmaster/DefaultSlotPoolServiceSchedulerFactory.java
+++ b/flink-runtime/src/main/java/org/apache/flink/runtime/jobmaster/DefaultSlotPoolServiceSchedulerFactory.java
@@ -23,7 +23,6 @@ import org.apache.flink.api.common.JobID;
 import org.apache.flink.api.common.time.Time;
 import org.apache.flink.configuration.AkkaOptions;
 import org.apache.flink.configuration.CheckpointingOptions;
-import org.apache.flink.configuration.ClusterOptions;
 import org.apache.flink.configuration.Configuration;
 import org.apache.flink.configuration.JobManagerOptions;
 import org.apache.flink.configuration.SchedulerExecutionMode;
@@ -147,7 +146,7 @@ public final class DefaultSlotPoolServiceSchedulerFactory
     }
 
     public static DefaultSlotPoolServiceSchedulerFactory fromConfiguration(
-            Configuration configuration, JobType jobType) {
+            Configuration configuration, JobType jobType, boolean isDynamicGraph) {
 
         final Time rpcTimeout =
                 Time.fromDuration(configuration.get(AkkaOptions.ASK_TIMEOUT_DURATION));
@@ -160,7 +159,7 @@ public final class DefaultSlotPoolServiceSchedulerFactory
         final SchedulerNGFactory schedulerNGFactory;
 
         JobManagerOptions.SchedulerType schedulerType =
-                ClusterOptions.getSchedulerType(configuration);
+                getSchedulerType(configuration, jobType, isDynamicGraph);
         if (schedulerType == JobManagerOptions.SchedulerType.Adaptive && jobType == JobType.BATCH) {
             LOG.info(
                     "Adaptive Scheduler configured, but Batch job detected. Changing scheduler type to 'Default'.");
@@ -223,6 +222,24 @@ public final class DefaultSlotPoolServiceSchedulerFactory
                 slotPoolServiceFactory, schedulerNGFactory);
     }
 
+    private static JobManagerOptions.SchedulerType getSchedulerType(
+            Configuration configuration, JobType jobType, boolean isDynamicGraph) {
+        if (configuration.get(JobManagerOptions.SCHEDULER_MODE)
+                == SchedulerExecutionMode.REACTIVE) {
+            return JobManagerOptions.SchedulerType.Adaptive;
+        } else {
+            return configuration
+                    .getOptional(JobManagerOptions.SCHEDULER)
+                    .orElse(
+                            System.getProperties()
+                                            .containsKey("flink.tests.enable-adaptive-scheduler")
+                                    ? JobManagerOptions.SchedulerType.Adaptive
+                                    : (jobType == JobType.BATCH && isDynamicGraph
+                                            ? JobManagerOptions.SchedulerType.AdaptiveBatch
+                                            : JobManagerOptions.SchedulerType.Default));
+        }
+    }
+
     @VisibleForTesting
     static RequestSlotMatchingStrategy getRequestSlotMatchingStrategy(
             Configuration configuration, JobType jobType) {
diff --git a/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/DefaultSlotPoolServiceSchedulerFactoryTest.java b/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/DefaultSlotPoolServiceSchedulerFactoryTest.java
index 9e64477f8d1..924b4cfbc94 100644
--- a/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/DefaultSlotPoolServiceSchedulerFactoryTest.java
+++ b/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/DefaultSlotPoolServiceSchedulerFactoryTest.java
@@ -51,7 +51,7 @@ public class DefaultSlotPoolServiceSchedulerFactoryTest {
 
         final DefaultSlotPoolServiceSchedulerFactory defaultSlotPoolServiceSchedulerFactory =
                 DefaultSlotPoolServiceSchedulerFactory.fromConfiguration(
-                        configuration, JobType.BATCH);
+                        configuration, JobType.BATCH, true);
 
         assertThat(defaultSlotPoolServiceSchedulerFactory.getSchedulerNGFactory())
                 .isInstanceOf(DefaultSchedulerFactory.class);
@@ -66,7 +66,7 @@ public class DefaultSlotPoolServiceSchedulerFactoryTest {
 
         final DefaultSlotPoolServiceSchedulerFactory defaultSlotPoolServiceSchedulerFactory =
                 DefaultSlotPoolServiceSchedulerFactory.fromConfiguration(
-                        configuration, JobType.STREAMING);
+                        configuration, JobType.STREAMING, false);
 
         assertThat(defaultSlotPoolServiceSchedulerFactory.getSchedulerNGFactory())
                 .isInstanceOf(AdaptiveSchedulerFactory.class);
diff --git a/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/JobMasterTest.java b/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/JobMasterTest.java
index 5372ebc4ef4..8abc3c68179 100644
--- a/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/JobMasterTest.java
+++ b/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/JobMasterTest.java
@@ -97,6 +97,7 @@ import org.apache.flink.runtime.rpc.TestingRpcService;
 import org.apache.flink.runtime.rpc.exceptions.RecipientUnreachableException;
 import org.apache.flink.runtime.scheduler.DefaultSchedulerFactory;
 import org.apache.flink.runtime.scheduler.ExecutionGraphInfo;
+import org.apache.flink.runtime.scheduler.SchedulerTestingUtils;
 import org.apache.flink.runtime.scheduler.TestingSchedulerNG;
 import org.apache.flink.runtime.scheduler.TestingSchedulerNGFactory;
 import org.apache.flink.runtime.state.CompletedCheckpointStorageLocation;
@@ -1367,7 +1368,8 @@ class JobMasterTest {
             // finish the producer task
             jobMasterGateway
                     .updateTaskExecutionState(
-                            new TaskExecutionState(executionAttemptId, ExecutionState.FINISHED))
+                            SchedulerTestingUtils.createFinishedTaskExecutionState(
+                                    executionAttemptId))
                     .get();
 
             // request the state of the result partition of the producer
@@ -1947,12 +1949,11 @@ class JobMasterTest {
             // 1 slot reserved, 1 slot free
             jobMasterGateway
                     .updateTaskExecutionState(
-                            new TaskExecutionState(
+                            SchedulerTestingUtils.createFinishedTaskExecutionState(
                                     getExecutions(jobMasterGateway)
                                             .iterator()
                                             .next()
-                                            .getAttemptId(),
-                                    ExecutionState.FINISHED))
+                                            .getAttemptId()))
                     .get();
 
             BlockedNode blockedNode =
@@ -2163,8 +2164,10 @@ class JobMasterTest {
     private JobGraph producerConsumerJobGraph() {
         final JobVertex producer = new JobVertex("Producer");
         producer.setInvokableClass(NoOpInvokable.class);
+        producer.setParallelism(1);
         final JobVertex consumer = new JobVertex("Consumer");
         consumer.setInvokableClass(NoOpInvokable.class);
+        consumer.setParallelism(1);
 
         consumer.connectNewDataSetAsInput(
                 producer, DistributionPattern.POINTWISE, ResultPartitionType.BLOCKING);
diff --git a/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/utils/JobMasterBuilder.java b/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/utils/JobMasterBuilder.java
index 8e3c774081b..5c558449143 100644
--- a/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/utils/JobMasterBuilder.java
+++ b/flink-runtime/src/test/java/org/apache/flink/runtime/jobmaster/utils/JobMasterBuilder.java
@@ -197,7 +197,7 @@ public class JobMasterBuilder {
                 slotPoolServiceSchedulerFactory != null
                         ? slotPoolServiceSchedulerFactory
                         : DefaultSlotPoolServiceSchedulerFactory.fromConfiguration(
-                                configuration, jobGraph.getJobType()),
+                                configuration, jobGraph.getJobType(), jobGraph.isDynamic()),
                 jobManagerSharedServices != null
                         ? jobManagerSharedServices
                         : new TestingJobManagerSharedServicesBuilder().build(),
diff --git a/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptivebatch/AdaptiveBatchSchedulerTest.java b/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptivebatch/AdaptiveBatchSchedulerTest.java
index b343ea6749b..014398530b9 100644
--- a/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptivebatch/AdaptiveBatchSchedulerTest.java
+++ b/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptivebatch/AdaptiveBatchSchedulerTest.java
@@ -20,7 +20,6 @@
 package org.apache.flink.runtime.scheduler.adaptivebatch;
 
 import org.apache.flink.api.common.JobID;
-import org.apache.flink.configuration.Configuration;
 import org.apache.flink.configuration.JobManagerOptions;
 import org.apache.flink.runtime.concurrent.ComponentMainThreadExecutor;
 import org.apache.flink.runtime.concurrent.ComponentMainThreadExecutorServiceAdapter;
@@ -162,10 +161,6 @@ class AdaptiveBatchSchedulerTest {
         JobVertex source2 = jobVertexIterator.next();
         JobVertex sink = jobVertexIterator.next();
 
-        Configuration configuration = new Configuration();
-        configuration.set(
-                JobManagerOptions.SCHEDULER, JobManagerOptions.SchedulerType.AdaptiveBatch);
-
         final TestingJobMasterPartitionTracker partitionTracker =
                 new TestingJobMasterPartitionTracker();
         partitionTracker.setIsPartitionTrackedFunction(ignore -> true);
@@ -175,7 +170,6 @@ class AdaptiveBatchSchedulerTest {
                 new DefaultSchedulerBuilder(
                                 jobGraph, mainThreadExecutor, EXECUTOR_RESOURCE.getExecutor())
                         .setDelayExecutor(taskRestartExecutor)
-                        .setJobMasterConfiguration(configuration)
                         .setPartitionTracker(partitionTracker)
                         .setRestartBackoffTimeStrategy(
                                 new FixedDelayRestartBackoffTimeStrategy
@@ -407,14 +401,9 @@ class AdaptiveBatchSchedulerTest {
             VertexParallelismAndInputInfosDecider vertexParallelismAndInputInfosDecider,
             int defaultMaxParallelism)
             throws Exception {
-        Configuration configuration = new Configuration();
-        configuration.set(
-                JobManagerOptions.SCHEDULER, JobManagerOptions.SchedulerType.AdaptiveBatch);
-
         return new DefaultSchedulerBuilder(
                         jobGraph, mainThreadExecutor, EXECUTOR_RESOURCE.getExecutor())
                 .setDelayExecutor(taskRestartExecutor)
-                .setJobMasterConfiguration(configuration)
                 .setVertexParallelismAndInputInfosDecider(vertexParallelismAndInputInfosDecider)
                 .setDefaultMaxParallelism(defaultMaxParallelism)
                 .buildAdaptiveBatchJobScheduler();
diff --git a/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamGraph.java b/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamGraph.java
index 5b85b9e7773..693822a83fe 100644
--- a/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamGraph.java
+++ b/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamGraph.java
@@ -139,6 +139,8 @@ public class StreamGraph implements Pipeline {
 
     private final List<JobStatusHook> jobStatusHooks = new ArrayList<>();
 
+    private boolean dynamic;
+
     public StreamGraph(
             ExecutionConfig executionConfig,
             CheckpointConfig checkpointConfig,
@@ -689,9 +691,7 @@ public class StreamGraph implements Pipeline {
         if (partitioner == null
                 && upstreamNode.getParallelism() == downstreamNode.getParallelism()) {
             partitioner =
-                    executionConfig.isDynamicGraph()
-                            ? new ForwardForUnspecifiedPartitioner<>()
-                            : new ForwardPartitioner<>();
+                    dynamic ? new ForwardForUnspecifiedPartitioner<>() : new ForwardPartitioner<>();
         } else if (partitioner == null) {
             partitioner = new RebalancePartitioner<Object>();
         }
@@ -751,6 +751,14 @@ public class StreamGraph implements Pipeline {
         }
     }
 
+    public boolean isDynamic() {
+        return dynamic;
+    }
+
+    public void setDynamic(boolean dynamic) {
+        this.dynamic = dynamic;
+    }
+
     public void setMaxParallelism(int vertexID, int maxParallelism) {
         if (getStreamNode(vertexID) != null) {
             getStreamNode(vertexID).setMaxParallelism(maxParallelism);
diff --git a/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamGraphGenerator.java b/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamGraphGenerator.java
index 2cdf4fc739e..1263cb64bfa 100644
--- a/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamGraphGenerator.java
+++ b/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamGraphGenerator.java
@@ -32,6 +32,7 @@ import org.apache.flink.configuration.ClusterOptions;
 import org.apache.flink.configuration.Configuration;
 import org.apache.flink.configuration.ExecutionOptions;
 import org.apache.flink.configuration.IllegalConfigurationException;
+import org.apache.flink.configuration.JobManagerOptions;
 import org.apache.flink.configuration.MemorySize;
 import org.apache.flink.configuration.PipelineOptions;
 import org.apache.flink.configuration.ReadableConfig;
@@ -98,6 +99,7 @@ import java.util.HashMap;
 import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 import static org.apache.flink.util.Preconditions.checkNotNull;
@@ -323,6 +325,15 @@ public class StreamGraphGenerator {
 
         setFineGrainedGlobalStreamExchangeMode(streamGraph);
 
+        Optional<JobManagerOptions.SchedulerType> schedulerTypeOptional =
+                executionConfig.getSchedulerType();
+        boolean dynamic =
+                shouldExecuteInBatchMode
+                        && schedulerTypeOptional.orElse(
+                                        JobManagerOptions.SchedulerType.AdaptiveBatch)
+                                == JobManagerOptions.SchedulerType.AdaptiveBatch;
+        streamGraph.setDynamic(dynamic);
+
         for (StreamNode node : streamGraph.getStreamNodes()) {
             if (node.getInEdges().stream().anyMatch(this::shouldDisableUnalignedCheckpointing)) {
                 for (StreamEdge edge : node.getInEdges()) {
diff --git a/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamingJobGraphGenerator.java b/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamingJobGraphGenerator.java
index eafe8ae128e..b810ea604ee 100644
--- a/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamingJobGraphGenerator.java
+++ b/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/graph/StreamingJobGraphGenerator.java
@@ -220,6 +220,7 @@ public class StreamingJobGraphGenerator {
     private JobGraph createJobGraph() {
         preValidate();
         jobGraph.setJobType(streamGraph.getJobType());
+        jobGraph.setDynamic(streamGraph.isDynamic());
 
         jobGraph.enableApproximateLocalRecovery(
                 streamGraph.getCheckpointConfig().isApproximateLocalRecoveryEnabled());
@@ -1105,7 +1106,7 @@ public class StreamingJobGraphGenerator {
             if (partitioner instanceof ForwardForConsecutiveHashPartitioner
                     || partitioner instanceof ForwardForUnspecifiedPartitioner) {
                 checkState(
-                        streamGraph.getExecutionConfig().isDynamicGraph(),
+                        streamGraph.isDynamic(),
                         String.format(
                                 "%s should only be used in dynamic graph.",
                                 partitioner.getClass().getSimpleName()));
@@ -1116,14 +1117,14 @@ public class StreamingJobGraphGenerator {
             StreamPartitioner<?> partitioner = edge.getPartitioner();
             if (partitioner instanceof ForwardForConsecutiveHashPartitioner) {
                 checkState(
-                        streamGraph.getExecutionConfig().isDynamicGraph(),
+                        streamGraph.isDynamic(),
                         "ForwardForConsecutiveHashPartitioner should only be used in dynamic graph.");
                 edge.setPartitioner(
                         ((ForwardForConsecutiveHashPartitioner<?>) partitioner)
                                 .getHashPartitioner());
             } else if (partitioner instanceof ForwardForUnspecifiedPartitioner) {
                 checkState(
-                        streamGraph.getExecutionConfig().isDynamicGraph(),
+                        streamGraph.isDynamic(),
                         "ForwardForUnspecifiedPartitioner should only be used in dynamic graph.");
                 edge.setPartitioner(new RescalePartitioner<>());
             }
@@ -1287,9 +1288,7 @@ public class StreamingJobGraphGenerator {
         if (!(upStreamVertex.isSameSlotSharingGroup(downStreamVertex)
                 && areOperatorsChainable(upStreamVertex, downStreamVertex, streamGraph)
                 && arePartitionerAndExchangeModeChainable(
-                        edge.getPartitioner(),
-                        edge.getExchangeMode(),
-                        streamGraph.getExecutionConfig().isDynamicGraph())
+                        edge.getPartitioner(), edge.getExchangeMode(), streamGraph.isDynamic())
                 && upStreamVertex.getParallelism() == downStreamVertex.getParallelism()
                 && streamGraph.isChainingEnabled())) {
 
diff --git a/flink-streaming-java/src/test/java/org/apache/flink/streaming/runtime/partitioner/StreamPartitionerTestUtils.java b/flink-streaming-java/src/test/java/org/apache/flink/streaming/runtime/partitioner/StreamPartitionerTestUtils.java
index 5ac50c654a0..81df8444c57 100644
--- a/flink-streaming-java/src/test/java/org/apache/flink/streaming/runtime/partitioner/StreamPartitionerTestUtils.java
+++ b/flink-streaming-java/src/test/java/org/apache/flink/streaming/runtime/partitioner/StreamPartitionerTestUtils.java
@@ -19,8 +19,6 @@ package org.apache.flink.streaming.runtime.partitioner;
 
 import org.apache.flink.api.common.RuntimeExecutionMode;
 import org.apache.flink.configuration.Configuration;
-import org.apache.flink.configuration.JobManagerOptions;
-import org.apache.flink.configuration.JobManagerOptions.SchedulerType;
 import org.apache.flink.runtime.jobgraph.JobGraph;
 import org.apache.flink.streaming.api.datastream.DataStream;
 import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
@@ -49,7 +47,6 @@ public class StreamPartitionerTestUtils {
             StreamExchangeMode exchangeMode) {
 
         Configuration configuration = new Configuration();
-        configuration.set(JobManagerOptions.SCHEDULER, SchedulerType.AdaptiveBatch);
         final StreamExecutionEnvironment env =
                 StreamExecutionEnvironment.getExecutionEnvironment(configuration);
         env.setRuntimeMode(RuntimeExecutionMode.BATCH);
diff --git a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/plan/nodes/exec/processor/ForwardHashExchangeProcessor.java b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/plan/nodes/exec/processor/ForwardHashExchangeProcessor.java
index 9e03ac9da96..07ae2c2f5d2 100644
--- a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/plan/nodes/exec/processor/ForwardHashExchangeProcessor.java
+++ b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/plan/nodes/exec/processor/ForwardHashExchangeProcessor.java
@@ -17,6 +17,7 @@
 
 package org.apache.flink.table.planner.plan.nodes.exec.processor;
 
+import org.apache.flink.configuration.JobManagerOptions;
 import org.apache.flink.configuration.ReadableConfig;
 import org.apache.flink.table.api.TableException;
 import org.apache.flink.table.planner.plan.nodes.exec.ExecEdge;
@@ -67,7 +68,13 @@ public class ForwardHashExchangeProcessor implements ExecNodeGraphProcessor {
         if (execGraph.getRootNodes().get(0) instanceof StreamExecNode) {
             throw new TableException("StreamExecNode is not supported yet");
         }
-        if (!context.getPlanner().getExecEnv().getConfig().isDynamicGraph()) {
+        JobManagerOptions.SchedulerType schedulerType =
+                context.getPlanner()
+                        .getExecEnv()
+                        .getConfig()
+                        .getSchedulerType()
+                        .orElse(JobManagerOptions.SchedulerType.AdaptiveBatch);
+        if (schedulerType != JobManagerOptions.SchedulerType.AdaptiveBatch) {
             return execGraph;
         }
         ReadableConfig tableConfig = context.getPlanner().getTableConfig();
diff --git a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/DynamicFilteringITCase.java b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/DynamicFilteringITCase.java
index 45ea9cf6ca6..f4cf3de070d 100644
--- a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/DynamicFilteringITCase.java
+++ b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/DynamicFilteringITCase.java
@@ -20,6 +20,7 @@ package org.apache.flink.table.planner.runtime.batch.sql;
 
 import org.apache.flink.api.common.BatchShuffleMode;
 import org.apache.flink.configuration.ExecutionOptions;
+import org.apache.flink.configuration.JobManagerOptions;
 import org.apache.flink.table.api.TableEnvironment;
 import org.apache.flink.table.api.config.ExecutionConfigOptions;
 import org.apache.flink.table.api.config.OptimizerConfigOptions;
@@ -127,7 +128,7 @@ public class DynamicFilteringITCase extends BatchTestBase {
     @ParameterizedTest(name = "mode = {0}")
     @MethodSource("parameters")
     public void testSimpleDynamicFiltering(BatchShuffleMode shuffleMode) {
-        tEnv.getConfig().getConfiguration().set(ExecutionOptions.BATCH_SHUFFLE_MODE, shuffleMode);
+        configure(shuffleMode);
         checkResult(
                 "SELECT * FROM fact1, dim WHERE x = a AND z = 2",
                 JavaScalaConversionUtil.toScala(
@@ -157,7 +158,7 @@ public class DynamicFilteringITCase extends BatchTestBase {
     @MethodSource("parameters")
     public void testDynamicFilteringChainWithMultipleInput(BatchShuffleMode shuffleMode)
             throws Exception {
-        tEnv.getConfig().getConfiguration().set(ExecutionOptions.BATCH_SHUFFLE_MODE, shuffleMode);
+        configure(shuffleMode);
         String dataId1 = TestValuesTableFactory.registerData(TestData.data7());
         tEnv.executeSql(
                 String.format(
@@ -203,7 +204,7 @@ public class DynamicFilteringITCase extends BatchTestBase {
     @ParameterizedTest(name = "mode = {0}")
     @MethodSource("parameters")
     public void testDynamicFilteringCannotChainWithMultipleInput(BatchShuffleMode shuffleMode) {
-        tEnv.getConfig().getConfiguration().set(ExecutionOptions.BATCH_SHUFFLE_MODE, shuffleMode);
+        configure(shuffleMode);
         checkResult(
                 "SELECT * FROM fact1, dim, fact2 WHERE x = fact1.a and fact2.a = fact1.a AND z = 1 and fact1.e = 2 and fact2.e = 1",
                 JavaScalaConversionUtil.toScala(
@@ -234,7 +235,7 @@ public class DynamicFilteringITCase extends BatchTestBase {
     @ParameterizedTest(name = "mode = {0}")
     @MethodSource("parameters")
     public void testReuseDimSide(BatchShuffleMode shuffleMode) {
-        tEnv.getConfig().getConfiguration().set(ExecutionOptions.BATCH_SHUFFLE_MODE, shuffleMode);
+        configure(shuffleMode);
         checkResult(
                 "SELECT * FROM fact1, dim WHERE x = a AND z = 1 and b = 3"
                         + "UNION ALL "
@@ -249,7 +250,7 @@ public class DynamicFilteringITCase extends BatchTestBase {
     @ParameterizedTest(name = "mode = {0}")
     @MethodSource("parameters")
     public void testDynamicFilteringWithStaticPartitionPruning(BatchShuffleMode shuffleMode) {
-        tEnv.getConfig().getConfiguration().set(ExecutionOptions.BATCH_SHUFFLE_MODE, shuffleMode);
+        configure(shuffleMode);
         checkResult(
                 "SELECT * FROM fact2, dim WHERE x = a and e = z AND y < 5 and a = 3",
                 JavaScalaConversionUtil.toScala(
@@ -263,7 +264,7 @@ public class DynamicFilteringITCase extends BatchTestBase {
     @ParameterizedTest(name = "mode = {0}")
     @MethodSource("parameters")
     public void testMultiplePartitionKeysWithFullKey(BatchShuffleMode shuffleMode) {
-        tEnv.getConfig().getConfiguration().set(ExecutionOptions.BATCH_SHUFFLE_MODE, shuffleMode);
+        configure(shuffleMode);
         checkResult(
                 "SELECT * FROM fact2, dim WHERE x = a AND z = e and y = 1",
                 JavaScalaConversionUtil.toScala(
@@ -274,7 +275,7 @@ public class DynamicFilteringITCase extends BatchTestBase {
     @ParameterizedTest(name = "mode = {0}")
     @MethodSource("parameters")
     public void testMultiplePartitionKeysWithPartialKey(BatchShuffleMode shuffleMode) {
-        tEnv.getConfig().getConfiguration().set(ExecutionOptions.BATCH_SHUFFLE_MODE, shuffleMode);
+        configure(shuffleMode);
         checkResult(
                 "SELECT * FROM fact2, dim WHERE z = e and y = 1",
                 JavaScalaConversionUtil.toScala(
@@ -286,4 +287,19 @@ public class DynamicFilteringITCase extends BatchTestBase {
                                 Row.of(5, 11, 10, "GHI", 1, 2, 1, 1))),
                 false);
     }
+
+    private void configure(BatchShuffleMode shuffleMode) {
+        tEnv.getConfig().getConfiguration().set(ExecutionOptions.BATCH_SHUFFLE_MODE, shuffleMode);
+        if (shuffleMode == BatchShuffleMode.ALL_EXCHANGES_PIPELINED) {
+            tEnv.getConfig()
+                    .getConfiguration()
+                    .set(JobManagerOptions.SCHEDULER, JobManagerOptions.SchedulerType.Default);
+        } else {
+            tEnv.getConfig()
+                    .getConfiguration()
+                    .set(
+                            JobManagerOptions.SCHEDULER,
+                            JobManagerOptions.SchedulerType.AdaptiveBatch);
+        }
+    }
 }
diff --git a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/join/AdaptiveHashJoinITCase.java b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/join/AdaptiveHashJoinITCase.java
index 6f975c7fb5d..2e7bd7e05e2 100644
--- a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/join/AdaptiveHashJoinITCase.java
+++ b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/join/AdaptiveHashJoinITCase.java
@@ -18,9 +18,7 @@
 
 package org.apache.flink.table.planner.runtime.batch.sql.join;
 
-import org.apache.flink.api.common.BatchShuffleMode;
 import org.apache.flink.configuration.Configuration;
-import org.apache.flink.configuration.ExecutionOptions;
 import org.apache.flink.configuration.MemorySize;
 import org.apache.flink.configuration.TaskManagerOptions;
 import org.apache.flink.runtime.testutils.MiniClusterResourceConfiguration;
@@ -76,8 +74,6 @@ public class AdaptiveHashJoinITCase extends TestLogger {
         tEnv.getConfig()
                 .getConfiguration()
                 .set(ExecutionConfigOptions.TABLE_EXEC_RESOURCE_DEFAULT_PARALLELISM, 1);
-        tEnv.getConfig()
-                .set(ExecutionOptions.BATCH_SHUFFLE_MODE, BatchShuffleMode.ALL_EXCHANGES_PIPELINED);
 
         JoinITCaseHelper.disableOtherJoinOpForJoin(tEnv, JoinType.HashJoin());
 
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/DagOptimizationTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/DagOptimizationTest.xml
index d7d46e3db3b..6a7353a1fd7 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/DagOptimizationTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/DagOptimizationTest.xml
@@ -273,7 +273,7 @@ Calc(select=[a AS a1, b, c AS c2])(reuse_id=[3])
    :- Exchange(distribution=[hash[a]])
    :  +- Calc(select=[a, b], where=[(a <= 10)])
    :     +- Reused(reference_id=[1])
-   +- Exchange(distribution=[hash[a2]], shuffle_mode=[BATCH])
+   +- Exchange(distribution=[hash[a2]])
       +- Calc(select=[a AS a2, c], where=[(b >= 5)])
          +- Reused(reference_id=[2])
 
@@ -720,11 +720,11 @@ LogicalLegacySink(name=[`default_catalog`.`default_database`.`appendSink`], fiel
       <![CDATA[
 LegacySink(name=[`default_catalog`.`default_database`.`appendSink`], fields=[a1, b, c1])
 +- Calc(select=[a1, b, c1])
-   +- MultipleInput(readOrder=[2,1,0], members=[\nHashJoin(joinType=[InnerJoin], where=[(a1 = a3)], select=[a3, c1, a1, b], build=[right])\n:- [#1] Exchange(distribution=[hash[a3]], shuffle_mode=[BATCH])\n+- Calc(select=[a AS a1, b])\n   +- HashJoin(joinType=[InnerJoin], where=[(a = a2)], select=[a, b, a2], build=[right])\n      :- [#2] Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])\n      +- [#3] Exchange(distribution=[hash[a2]])\n])
-      :- Exchange(distribution=[hash[a3]], shuffle_mode=[BATCH])
+   +- MultipleInput(readOrder=[2,1,0], members=[\nHashJoin(joinType=[InnerJoin], where=[(a1 = a3)], select=[a3, c1, a1, b], build=[right])\n:- [#1] Exchange(distribution=[hash[a3]])\n+- Calc(select=[a AS a1, b])\n   +- HashJoin(joinType=[InnerJoin], where=[(a = a2)], select=[a, b, a2], build=[right])\n      :- [#2] Exchange(distribution=[hash[a]])\n      +- [#3] Exchange(distribution=[hash[a2]])\n])
+      :- Exchange(distribution=[hash[a3]])
       :  +- Calc(select=[a AS a3, c AS c1], where=[((a >= 0) AND (b < 5))])
       :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])(reuse_id=[1])
-      :- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
+      :- Exchange(distribution=[hash[a]])
       :  +- Calc(select=[a, b], where=[(a <= 10)])
       :     +- Reused(reference_id=[1])
       +- Exchange(distribution=[hash[a2]])
@@ -801,14 +801,14 @@ LogicalLegacySink(name=[`default_catalog`.`default_database`.`sink`], fields=[a,
       <![CDATA[
 LegacySink(name=[`default_catalog`.`default_database`.`sink`], fields=[a, b, c])
 +- Calc(select=[a AS a1, b1, c1])
-   +- MultipleInput(readOrder=[3,2,1,0], members=[\nHashJoin(joinType=[InnerJoin], where=[(a = a3)], select=[a, a3, b1, c1], build=[right])\n:- [#1] Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])\n+- Calc(select=[a3, b AS b1, c1])\n   +- HashJoin(joinType=[InnerJoin], where=[(a1 = a3)], select=[a3, c1, a1, b], build=[right])\n      :- [#2] Exchange(distribution=[hash[a3]], shuffle_mode=[BATCH])\n      +- Calc(select=[a AS a1, b])\n         +- HashJoin(joinType=[InnerJoin], where= [...]
-      :- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
+   +- MultipleInput(readOrder=[3,2,1,0], members=[\nHashJoin(joinType=[InnerJoin], where=[(a = a3)], select=[a, a3, b1, c1], build=[right])\n:- [#1] Exchange(distribution=[hash[a]])\n+- Calc(select=[a3, b AS b1, c1])\n   +- HashJoin(joinType=[InnerJoin], where=[(a1 = a3)], select=[a3, c1, a1, b], build=[right])\n      :- [#2] Exchange(distribution=[hash[a3]])\n      +- Calc(select=[a AS a1, b])\n         +- HashJoin(joinType=[InnerJoin], where=[(a = a2)], select=[a, b, a2], build=[right] [...]
+      :- Exchange(distribution=[hash[a]])
       :  +- Calc(select=[a], where=[(a <= 10)])
       :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])(reuse_id=[1])
-      :- Exchange(distribution=[hash[a3]], shuffle_mode=[BATCH])
+      :- Exchange(distribution=[hash[a3]])
       :  +- Calc(select=[a AS a3, c AS c1], where=[((a >= 0) AND (b < 5))])
       :     +- Reused(reference_id=[1])
-      :- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
+      :- Exchange(distribution=[hash[a]])
       :  +- Calc(select=[a, b], where=[(a <= 10)])
       :     +- Reused(reference_id=[1])
       +- Exchange(distribution=[hash[a2]])
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/DeadlockBreakupTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/DeadlockBreakupTest.xml
index 1e7a5089851..df69ff98aba 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/DeadlockBreakupTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/DeadlockBreakupTest.xml
@@ -32,11 +32,12 @@ LogicalIntersect(all=[false])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashAggregate(isMerge=[false], groupBy=[a, b, c], select=[a, b, c])
-+- HashJoin(joinType=[LeftSemiJoin], where=[(((a = a0) OR (a IS NULL AND a0 IS NULL)) AND ((b = b0) OR (b IS NULL AND b0 IS NULL)) AND ((c = c0) OR (c IS NULL AND c0 IS NULL)))], select=[a, b, c], build=[left])
-   :- Exchange(distribution=[hash[a, b, c]])
-   :  +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
-   +- Exchange(distribution=[hash[a, b, c]], shuffle_mode=[BATCH])
-      +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
++- Exchange(distribution=[keep_input_as_is[hash[a, b, c]]])
+   +- HashJoin(joinType=[LeftSemiJoin], where=[(((a = a0) OR (a IS NULL AND a0 IS NULL)) AND ((b = b0) OR (b IS NULL AND b0 IS NULL)) AND ((c = c0) OR (c IS NULL AND c0 IS NULL)))], select=[a, b, c], build=[left])
+      :- Exchange(distribution=[hash[a, b, c]])
+      :  +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
+      +- Exchange(distribution=[hash[a, b, c]], shuffle_mode=[BATCH])
+         +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -318,11 +319,12 @@ LogicalUnion(all=[true])
     <Resource name="optimized exec plan">
       <![CDATA[
 MultipleInput(readOrder=[0,2,1], members=[\nUnion(all=[true], union=[cnt1, cnt2])\n:- Calc(select=[CAST(cnt1 AS BIGINT) AS cnt1, cnt2])\n:  +- HashJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, cnt1, d, cnt2], build=[right])\n:     :- HashAggregate(isMerge=[true], groupBy=[a], select=[a, Final_COUNT(count1$0) AS cnt1])(reuse_id=[1])\n:     :  +- [#3] Exchange(distribution=[hash[a]])\n:     +- [#1] HashAggregate(isMerge=[true], groupBy=[d], select=[d, Final_COUNT(count1$0) AS  [...]
-:- HashAggregate(isMerge=[true], groupBy=[d], select=[d, Final_COUNT(count1$0) AS cnt2])(reuse_id=[1])
-:  +- Exchange(distribution=[hash[d]])
-:     +- LocalHashAggregate(groupBy=[d], select=[d, Partial_COUNT(*) AS count1$0])
-:        +- Calc(select=[d])
-:           +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+:- Exchange(distribution=[keep_input_as_is[hash[d]]])
+:  +- HashAggregate(isMerge=[true], groupBy=[d], select=[d, Final_COUNT(count1$0) AS cnt2])(reuse_id=[1])
+:     +- Exchange(distribution=[hash[d]])
+:        +- LocalHashAggregate(groupBy=[d], select=[d, Partial_COUNT(*) AS count1$0])
+:           +- Calc(select=[d])
+:              +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 :- Exchange(distribution=[hash[d]], shuffle_mode=[BATCH])
 :  +- Reused(reference_id=[1])
 +- Exchange(distribution=[hash[a]])
@@ -369,19 +371,25 @@ LogicalProject(a=[$0], b=[$1], c=[$2], a0=[$3], b0=[$4], c0=[$5], a1=[$6], b1=[$
 HashJoin(joinType=[InnerJoin], where=[(c = c1)], select=[a, b, c, a0, b0, c0, a1, b1, c1, a00, b00, c00], build=[right])
 :- Exchange(distribution=[hash[c]])
 :  +- HashJoin(joinType=[InnerJoin], where=[(a = a0)], select=[a, b, c, a0, b0, c0], build=[left])
-:     :- Calc(select=[a, b, c], where=[(b > 10)])
-:     :  +- SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS b, Final_MAX(max$1) AS c])(reuse_id=[1])
-:     :     +- Sort(orderBy=[a ASC])
-:     :        +- Exchange(distribution=[hash[a]])
-:     :           +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_MAX(c) AS max$1])
+:     :- Exchange(distribution=[keep_input_as_is[hash[a]]])
+:     :  +- Calc(select=[a, b, c], where=[(b > 10)])
+:     :     +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+:     :        +- SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS b, Final_MAX(max$1) AS c])(reuse_id=[1])
+:     :           +- Exchange(distribution=[forward])
 :     :              +- Sort(orderBy=[a ASC])
-:     :                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+:     :                 +- Exchange(distribution=[hash[a]])
+:     :                    +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_MAX(c) AS max$1])
+:     :                       +- Exchange(distribution=[forward])
+:     :                          +- Sort(orderBy=[a ASC])
+:     :                             +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 :     +- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
 :        +- Reused(reference_id=[1])
 +- Exchange(distribution=[hash[c]])
    +- HashJoin(joinType=[InnerJoin], where=[(a = a0)], select=[a, b, c, a0, b0, c0], build=[left])
-      :- Calc(select=[a, b, c], where=[(b < 5)])
-      :  +- Reused(reference_id=[1])
+      :- Exchange(distribution=[keep_input_as_is[hash[a]]])
+      :  +- Calc(select=[a, b, c], where=[(b < 5)])
+      :     +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+      :        +- Reused(reference_id=[1])
       +- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
          +- Reused(reference_id=[1])
 ]]>
@@ -491,13 +499,15 @@ Calc(select=[a, b, a0, b0, c, k, CAST(0 AS BIGINT) AS v])
    :- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
    :  +- Calc(select=[a, b], where=[(a > 0)])(reuse_id=[2])
    :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])(reuse_id=[1])
-   +- Calc(select=[a, b, c, a0 AS k])
-      +- HashJoin(joinType=[InnerJoin], where=[((a = a0) AND ((b + b0) = 0))], select=[a, b, c, a0, b0], build=[right])
-         :- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
-         :  +- Calc(select=[a, b, c], where=[(a > 0)])
-         :     +- Reused(reference_id=[1])
-         +- Exchange(distribution=[hash[a]])
-            +- Reused(reference_id=[2])
+   +- Exchange(distribution=[keep_input_as_is[hash[k]]])
+      +- Calc(select=[a, b, c, a0 AS k])
+         +- Exchange(distribution=[keep_input_as_is[hash[a0]]])
+            +- HashJoin(joinType=[InnerJoin], where=[((a = a0) AND ((b + b0) = 0))], select=[a, b, c, a0, b0], build=[right])
+               :- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
+               :  +- Calc(select=[a, b, c], where=[(a > 0)])
+               :     +- Reused(reference_id=[1])
+               +- Exchange(distribution=[hash[a]])
+                  +- Reused(reference_id=[2])
 ]]>
     </Resource>
   </TestCase>
@@ -532,15 +542,19 @@ HashJoin(joinType=[InnerJoin], where=[(c = c0)], select=[a, b, c, a0, b0, c0], b
 :- Exchange(distribution=[hash[c]], shuffle_mode=[BATCH])
 :  +- Calc(select=[w0$o0 AS a, b, c])
 :     +- OverAggregate(partitionBy=[b], orderBy=[b ASC], window#0=[MAX(a) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[a, b, c, w0$o0])
-:        +- Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS a, b, c])(reuse_id=[1])
-:           +- OverAggregate(partitionBy=[b], orderBy=[b ASC], window#0=[COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o1])
-:              +- Sort(orderBy=[b ASC])
-:                 +- Exchange(distribution=[hash[b]])
-:                    +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+:        +- Exchange(distribution=[forward])
+:           +- Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS a, b, c])(reuse_id=[1])
+:              +- Exchange(distribution=[forward])
+:                 +- OverAggregate(partitionBy=[b], orderBy=[b ASC], window#0=[COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o1])
+:                    +- Exchange(distribution=[forward])
+:                       +- Sort(orderBy=[b ASC])
+:                          +- Exchange(distribution=[hash[b]])
+:                             +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 +- Exchange(distribution=[hash[c]])
    +- Calc(select=[w0$o0 AS a, b, c])
       +- OverAggregate(partitionBy=[b], orderBy=[b ASC], window#0=[MIN(a) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[a, b, c, w0$o0])
-         +- Reused(reference_id=[1])
+         +- Exchange(distribution=[forward])
+            +- Reused(reference_id=[1])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/MultipleInputCreationTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/MultipleInputCreationTest.xml
index 71e534e4058..ec5b58248f6 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/MultipleInputCreationTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/MultipleInputCreationTest.xml
@@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 -->
 <Root>
-  <TestCase name="testAvoidIncludingCalcAfterNonChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testAvoidIncludingCalcAfterNonChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM x
@@ -48,7 +48,7 @@ MultipleInput(readOrder=[0,1,0], members=[\nNestedLoopJoin(joinType=[LeftOuterJo
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testAvoidIncludingCalcAfterNonChainableSource[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testAvoidIncludingCalcAfterNonChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM x
@@ -80,7 +80,39 @@ MultipleInput(readOrder=[0,1,0], members=[\nNestedLoopJoin(joinType=[LeftOuterJo
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testIncludeCalcForChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testAvoidIncludingCalcAfterNonChainableSource[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+SELECT * FROM x
+  LEFT JOIN y ON x.a = y.d
+  LEFT JOIN t ON x.a = t.a
+  WHERE x.b > 10
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], b=[$1], c=[$2], nx=[$3], d=[$4], e=[$5], f=[$6], ny=[$7], a0=[$8], b0=[$9], c0=[$10])
++- LogicalFilter(condition=[>($1, 10)])
+   +- LogicalJoin(condition=[=($0, $8)], joinType=[left])
+      :- LogicalJoin(condition=[=($0, $4)], joinType=[left])
+      :  :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+      :  +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+      +- LogicalTableScan(table=[[default_catalog, default_database, t]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+MultipleInput(readOrder=[0,1,0], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = a0)], select=[a, b, c, nx, d, e, f, ny, a0, b0, c0], build=[right])\n:- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, b, c, nx, d, e, f, ny], build=[right])\n:  :- [#2] Calc(select=[a, b, c, nx], where=[(b > 10)])\n:  +- [#3] Exchange(distribution=[broadcast])\n+- [#1] Exchange(distribution=[broadcast])\n])
+:- Exchange(distribution=[broadcast])
+:  +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
+:- Calc(select=[a, b, c, nx], where=[(b > 10)])
+:  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
++- Exchange(distribution=[broadcast])
+   +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testIncludeCalcForChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM chainable
@@ -113,7 +145,7 @@ MultipleInput(readOrder=[0,0,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJo
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testAvoidIncludingSingleton[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testAvoidIncludingSingleton[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -169,7 +201,7 @@ Calc(select=[a])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testAvoidIncludingSingleton[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testAvoidIncludingSingleton[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -225,7 +257,96 @@ Calc(select=[a])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testAvoidIncludingUnionFromInputSide[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testAvoidIncludingSingleton[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+WITH
+  T1 AS (SELECT COUNT(*) AS cnt FROM z),
+  T2 AS (
+    SELECT a FROM
+      (SELECT a FROM x INNER JOIN y ON x.a = y.d)
+      UNION ALL
+      (SELECT a FROM t FULL JOIN T1 ON t.a > T1.cnt))
+SELECT a FROM T2 LEFT JOIN z ON T2.a = z.g
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0])
++- LogicalJoin(condition=[=($0, $1)], joinType=[left])
+   :- LogicalUnion(all=[true])
+   :  :- LogicalProject(a=[$0])
+   :  :  +- LogicalJoin(condition=[=($0, $4)], joinType=[inner])
+   :  :     :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+   :  :     +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+   :  +- LogicalProject(a=[$0])
+   :     +- LogicalJoin(condition=[>($0, $3)], joinType=[full])
+   :        :- LogicalTableScan(table=[[default_catalog, default_database, t]])
+   :        +- LogicalAggregate(group=[{}], cnt=[COUNT()])
+   :           +- LogicalProject($f0=[0])
+   :              +- LogicalTableScan(table=[[default_catalog, default_database, z, source: [TestTableSource(g, h, i, nz)]]])
+   +- LogicalTableScan(table=[[default_catalog, default_database, z, source: [TestTableSource(g, h, i, nz)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+Calc(select=[a])
++- MultipleInput(readOrder=[0,1,0,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = g)], select=[a, g], build=[right])\n:- Union(all=[true], union=[a])\n:  :- Calc(select=[a])\n:  :  +- NestedLoopJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[left])\n:  :     :- [#3] Exchange(distribution=[broadcast])\n:  :     +- [#4] Calc(select=[d])\n:  +- [#2] Calc(select=[a])\n+- [#1] Exchange(distribution=[broadcast])\n])
+   :- Exchange(distribution=[broadcast])
+   :  +- Calc(select=[g])
+   :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, z, source: [TestTableSource(g, h, i, nz)]]], fields=[g, h, i, nz])(reuse_id=[1])
+   :- Calc(select=[a])
+   :  +- NestedLoopJoin(joinType=[FullOuterJoin], where=[(a > cnt)], select=[a, cnt], build=[right], singleRowJoin=[true])
+   :     :- Exchange(distribution=[single])
+   :     :  +- Calc(select=[a])
+   :     :     +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
+   :     +- SortAggregate(isMerge=[true], select=[Final_COUNT(count1$0) AS cnt])
+   :        +- Exchange(distribution=[single])
+   :           +- LocalSortAggregate(select=[Partial_COUNT(*) AS count1$0])
+   :              +- Calc(select=[0 AS $f0])
+   :                 +- Reused(reference_id=[1])
+   :- Exchange(distribution=[broadcast])
+   :  +- Calc(select=[a])
+   :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+   +- Calc(select=[d])
+      +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testAvoidIncludingUnionFromInputSide[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
+    <Resource name="sql">
+      <![CDATA[
+SELECT * FROM
+  (SELECT a FROM (SELECT a FROM x) UNION ALL (SELECT a FROM t)) T1
+  LEFT JOIN y ON T1.a = y.d
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], d=[$1], e=[$2], f=[$3], ny=[$4])
++- LogicalJoin(condition=[=($0, $1)], joinType=[left])
+   :- LogicalUnion(all=[true])
+   :  :- LogicalProject(a=[$0])
+   :  :  +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+   :  +- LogicalProject(a=[$0])
+   :     +- LogicalTableScan(table=[[default_catalog, default_database, t]])
+   +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, d, e, f, ny], build=[right])
+:- Union(all=[true], union=[a])
+:  :- Calc(select=[a])
+:  :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+:  +- Calc(select=[a])
+:     +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
++- Exchange(distribution=[broadcast])
+   +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testAvoidIncludingUnionFromInputSide[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM
@@ -258,7 +379,7 @@ NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, d, e, f, ny
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testAvoidIncludingUnionFromInputSide[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testAvoidIncludingUnionFromInputSide[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM
@@ -291,7 +412,7 @@ NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, d, e, f, ny
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testBasicMultipleInput[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testBasicMultipleInput[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM
@@ -331,7 +452,47 @@ MultipleInput(readOrder=[2,1,1,0], members=[\nHashJoin(joinType=[InnerJoin], whe
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testCleanUpMultipleInputWithOneMember[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testBasicMultipleInput[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+SELECT * FROM
+  (SELECT a FROM x INNER JOIN y ON x.a = y.d) T1
+  INNER JOIN
+  (SELECT d FROM y INNER JOIN t ON y.d = t.a) T2
+  ON T1.a = T2.d
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], d=[$1])
++- LogicalJoin(condition=[=($0, $1)], joinType=[inner])
+   :- LogicalProject(a=[$0])
+   :  +- LogicalJoin(condition=[=($0, $4)], joinType=[inner])
+   :     :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+   :     +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+   +- LogicalProject(d=[$0])
+      +- LogicalJoin(condition=[=($0, $4)], joinType=[inner])
+         :- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+         +- LogicalTableScan(table=[[default_catalog, default_database, t]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+MultipleInput(readOrder=[2,1,1,0], members=[\nHashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[right])\n:- Calc(select=[a])\n:  +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[right])\n:     :- [#1] Exchange(distribution=[hash[a]])\n:     +- [#2] Exchange(distribution=[hash[d]])\n+- Calc(select=[d])\n   +- HashJoin(joinType=[InnerJoin], where=[(d = a)], select=[d, a], build=[right])\n      :- [#2] Exchange(distribution=[hash[d]])\n      +- [# [...]
+:- Exchange(distribution=[hash[a]])
+:  +- Calc(select=[a])
+:     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+:- Exchange(distribution=[hash[d]])(reuse_id=[1])
+:  +- Calc(select=[d])
+:     +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+:- Reused(reference_id=[1])
++- Exchange(distribution=[hash[a]])
+   +- Calc(select=[a])
+      +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testCleanUpMultipleInputWithOneMember[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -369,7 +530,7 @@ Union(all=[true], union=[a, EXPR$1])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testCleanUpMultipleInputWithOneMember[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testCleanUpMultipleInputWithOneMember[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -407,7 +568,82 @@ Union(all=[true], union=[a, EXPR$1])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testDeadlockCausedByExchangeInAncestor[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testCleanUpMultipleInputWithOneMember[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+WITH
+  T1 AS (SELECT a FROM x INNER JOIN y ON x.a = y.d)
+SELECT * FROM
+  (SELECT a, a + 1 FROM T1)
+  UNION ALL
+  (SELECT a, b FROM x)
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalUnion(all=[true])
+:- LogicalProject(a=[$0], EXPR$1=[+($0, 1)])
+:  +- LogicalJoin(condition=[=($0, $4)], joinType=[inner])
+:     :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+:     +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
++- LogicalProject(a=[$0], b=[$1])
+   +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+Union(all=[true], union=[a, EXPR$1])
+:- Calc(select=[a, CAST((a + 1) AS BIGINT) AS EXPR$1])
+:  +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[right])
+:     :- Exchange(distribution=[hash[a]])
+:     :  +- Calc(select=[a])
+:     :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])(reuse_id=[1])
+:     +- Exchange(distribution=[hash[d]])
+:        +- Calc(select=[d])
+:           +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
++- Calc(select=[a, b])
+   +- Reused(reference_id=[1])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testDeadlockCausedByExchangeInAncestor[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
+    <Resource name="sql">
+      <![CDATA[
+WITH T1 AS (
+  SELECT x1.*, x2.a AS k, (x1.b + x2.b) AS v
+  FROM x x1 LEFT JOIN x x2 ON x1.a = x2.a WHERE x2.a > 0)
+SELECT x.a, x.b, T1.* FROM x LEFT JOIN T1 ON x.a = T1.k WHERE x.a > 0 AND T1.v = 0
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], b=[$1], a0=[$4], b0=[$5], c=[$6], nx=[$7], k=[$8], v=[$9])
++- LogicalFilter(condition=[AND(>($0, 0), =($9, 0))])
+   +- LogicalJoin(condition=[=($0, $8)], joinType=[left])
+      :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+      +- LogicalProject(a=[$0], b=[$1], c=[$2], nx=[$3], k=[$4], v=[+($1, $5)])
+         +- LogicalFilter(condition=[>($4, 0)])
+            +- LogicalJoin(condition=[=($0, $4)], joinType=[left])
+               :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+               +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+Calc(select=[a, b, a0, b0, c, nx, k, CAST(0 AS BIGINT) AS v])
++- MultipleInput(readOrder=[2,1,0], members=[\nHashJoin(joinType=[InnerJoin], where=[(a = k)], select=[a, b, a0, b0, c, nx, k], build=[right])\n:- [#1] Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])\n+- Calc(select=[a, b, c, nx, a0 AS k])\n   +- HashJoin(joinType=[InnerJoin], where=[((a = a0) AND ((b + b0) = 0))], select=[a, b, c, nx, a0, b0], build=[right])\n      :- [#2] Exchange(distribution=[hash[a]])\n      +- [#3] Exchange(distribution=[hash[a]])\n])
+   :- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
+   :  +- Calc(select=[a, b], where=[(a > 0)])(reuse_id=[2])
+   :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])(reuse_id=[1])
+   :- Exchange(distribution=[hash[a]])
+   :  +- Calc(select=[a, b, c, nx], where=[(a > 0)])
+   :     +- Reused(reference_id=[1])
+   +- Exchange(distribution=[hash[a]])
+      +- Reused(reference_id=[2])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testDeadlockCausedByExchangeInAncestor[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH T1 AS (
@@ -444,7 +680,7 @@ Calc(select=[a, b, a0, b0, c, nx, k, CAST(0 AS BIGINT) AS v])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testDeadlockCausedByExchangeInAncestor[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testDeadlockCausedByExchangeInAncestor[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH T1 AS (
@@ -481,7 +717,7 @@ Calc(select=[a, b, a0, b0, c, nx, k, CAST(0 AS BIGINT) AS v])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testNoPriorityConstraint[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testNoPriorityConstraint[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM x
@@ -511,7 +747,7 @@ MultipleInput(members=[\nSortMergeJoin(joinType=[InnerJoin], where=[(a = a0)], s
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testBasicMultipleInput[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testBasicMultipleInput[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM
@@ -551,7 +787,40 @@ MultipleInput(readOrder=[2,1,1,0], members=[\nHashJoin(joinType=[InnerJoin], whe
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testIncludeCalcForChainableSource[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testIncludeCalcForChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+SELECT * FROM chainable
+  LEFT JOIN y ON chainable.a = y.d
+  LEFT JOIN t ON chainable.a = t.a
+  WHERE chainable.a > 10
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], d=[$1], e=[$2], f=[$3], ny=[$4], a0=[$5], b=[$6], c=[$7])
++- LogicalFilter(condition=[>($0, 10)])
+   +- LogicalJoin(condition=[=($0, $5)], joinType=[left])
+      :- LogicalJoin(condition=[=($0, $1)], joinType=[left])
+      :  :- LogicalTableScan(table=[[default_catalog, default_database, chainable]])
+      :  +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+      +- LogicalTableScan(table=[[default_catalog, default_database, t]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+MultipleInput(readOrder=[0,0,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = a0)], select=[a, d, e, f, ny, a0, b, c], build=[right])\n:- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, d, e, f, ny], build=[right])\n:  :- Calc(select=[a], where=[(a > 10)])\n:  :  +- [#3] BoundedStreamScan(table=[[default_catalog, default_database, chainable]], fields=[a])\n:  +- [#2] Exchange(distribution=[broadcast])\n+- [#1] Exchange(distribution=[broadcast])\n])
+:- Exchange(distribution=[broadcast])
+:  +- Calc(select=[a, b, c], where=[(a > 10)])
+:     +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
+:- Exchange(distribution=[broadcast])
+:  +- Calc(select=[d, e, f, ny], where=[(d > 10)])
+:     +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
++- BoundedStreamScan(table=[[default_catalog, default_database, chainable]], fields=[a])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testIncludeCalcForChainableSource[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM chainable
@@ -584,7 +853,7 @@ MultipleInput(readOrder=[0,0,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJo
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testIncludeUnionForChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testIncludeUnionForChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM
@@ -615,7 +884,7 @@ MultipleInput(readOrder=[0,1,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJo
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testIncludeUnionForChainableSource[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testIncludeUnionForChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM
@@ -646,7 +915,38 @@ MultipleInput(readOrder=[0,1,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJo
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testJoinWithAggAsProbe[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testIncludeUnionForChainableSource[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+SELECT * FROM
+  (SELECT a FROM (SELECT a FROM chainable) UNION ALL (SELECT a FROM t)) T1
+  LEFT JOIN y ON T1.a = y.d
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], d=[$1], e=[$2], f=[$3], ny=[$4])
++- LogicalJoin(condition=[=($0, $1)], joinType=[left])
+   :- LogicalUnion(all=[true])
+   :  :- LogicalProject(a=[$0])
+   :  :  +- LogicalTableScan(table=[[default_catalog, default_database, chainable]])
+   :  +- LogicalProject(a=[$0])
+   :     +- LogicalTableScan(table=[[default_catalog, default_database, t]])
+   +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+MultipleInput(readOrder=[0,1,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, d, e, f, ny], build=[right])\n:- Union(all=[true], union=[a])\n:  :- [#2] BoundedStreamScan(table=[[default_catalog, default_database, chainable]], fields=[a])\n:  +- [#3] Calc(select=[a])\n+- [#1] Exchange(distribution=[broadcast])\n])
+:- Exchange(distribution=[broadcast])
+:  +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+:- BoundedStreamScan(table=[[default_catalog, default_database, chainable]], fields=[a])
++- Calc(select=[a])
+   +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testJoinWithAggAsProbe[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 WITH T AS (SELECT a, d FROM x INNER JOIN y ON x.a = y.d)
@@ -678,20 +978,24 @@ LogicalProject(a=[$0], cnt=[$1], d=[$2], sm=[$3])
 HashJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, cnt, d, sm], build=[right])
 :- Exchange(distribution=[hash[a]])
 :  +- HashAggregate(isMerge=[false], groupBy=[a], select=[a, COUNT(*) AS cnt])
-:     +- Calc(select=[a])
-:        +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[right])(reuse_id=[1])
-:           :- Exchange(distribution=[hash[a]])
-:           :  +- Calc(select=[a])
-:           :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
-:           +- Exchange(distribution=[hash[d]])
-:              +- Calc(select=[d])
-:                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
-+- HashAggregate(isMerge=[false], groupBy=[d], select=[d, SUM(a) AS sm])
-   +- Reused(reference_id=[1])
+:     +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+:        +- Calc(select=[a])
+:           +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+:              +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[right])(reuse_id=[1])
+:                 :- Exchange(distribution=[hash[a]])
+:                 :  +- Calc(select=[a])
+:                 :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+:                 +- Exchange(distribution=[hash[d]])
+:                    +- Calc(select=[d])
+:                       +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
++- Exchange(distribution=[keep_input_as_is[hash[d]]])
+   +- HashAggregate(isMerge=[false], groupBy=[d], select=[d, SUM(a) AS sm])
+      +- Exchange(distribution=[keep_input_as_is[hash[d]]])
+         +- Reused(reference_id=[1])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testJoinWithAggAsProbe[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testJoinWithAggAsProbe[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH T AS (SELECT a, d FROM x INNER JOIN y ON x.a = y.d)
@@ -723,20 +1027,73 @@ LogicalProject(a=[$0], cnt=[$1], d=[$2], sm=[$3])
 HashJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, cnt, d, sm], build=[right])
 :- Exchange(distribution=[hash[a]])
 :  +- HashAggregate(isMerge=[false], groupBy=[a], select=[a, COUNT(*) AS cnt])
-:     +- Calc(select=[a])
-:        +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[right])(reuse_id=[1])
-:           :- Exchange(distribution=[hash[a]])
-:           :  +- Calc(select=[a])
-:           :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
-:           +- Exchange(distribution=[hash[d]])
-:              +- Calc(select=[d])
-:                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
-+- HashAggregate(isMerge=[false], groupBy=[d], select=[d, SUM(a) AS sm])
-   +- Reused(reference_id=[1])
+:     +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+:        +- Calc(select=[a])
+:           +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+:              +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[right])(reuse_id=[1])
+:                 :- Exchange(distribution=[hash[a]])
+:                 :  +- Calc(select=[a])
+:                 :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+:                 +- Exchange(distribution=[hash[d]])
+:                    +- Calc(select=[d])
+:                       +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
++- Exchange(distribution=[keep_input_as_is[hash[d]]])
+   +- HashAggregate(isMerge=[false], groupBy=[d], select=[d, SUM(a) AS sm])
+      +- Exchange(distribution=[keep_input_as_is[hash[d]]])
+         +- Reused(reference_id=[1])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testJoinWithAggAsProbe[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+WITH T AS (SELECT a, d FROM x INNER JOIN y ON x.a = y.d)
+SELECT * FROM
+  (SELECT a, COUNT(*) AS cnt FROM T GROUP BY a) T1
+  LEFT JOIN
+  (SELECT d, SUM(a) AS sm FROM T GROUP BY d) T2
+  ON T1.a = T2.d
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], cnt=[$1], d=[$2], sm=[$3])
++- LogicalJoin(condition=[=($0, $2)], joinType=[left])
+   :- LogicalAggregate(group=[{0}], cnt=[COUNT()])
+   :  +- LogicalProject(a=[$0])
+   :     +- LogicalJoin(condition=[=($0, $4)], joinType=[inner])
+   :        :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+   :        +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+   +- LogicalAggregate(group=[{0}], sm=[SUM($1)])
+      +- LogicalProject(d=[$4], a=[$0])
+         +- LogicalJoin(condition=[=($0, $4)], joinType=[inner])
+            :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+            +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+HashJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, cnt, d, sm], build=[right])
+:- Exchange(distribution=[hash[a]])
+:  +- HashAggregate(isMerge=[false], groupBy=[a], select=[a, COUNT(*) AS cnt])
+:     +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+:        +- Calc(select=[a])
+:           +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+:              +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[right])(reuse_id=[1])
+:                 :- Exchange(distribution=[hash[a]])
+:                 :  +- Calc(select=[a])
+:                 :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+:                 +- Exchange(distribution=[hash[d]])
+:                    +- Calc(select=[d])
+:                       +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
++- Exchange(distribution=[keep_input_as_is[hash[d]]])
+   +- HashAggregate(isMerge=[false], groupBy=[d], select=[d, SUM(a) AS sm])
+      +- Exchange(distribution=[keep_input_as_is[hash[d]]])
+         +- Reused(reference_id=[1])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testKeepMultipleInputWithOneMemberForChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testKeepMultipleInputWithOneMemberForChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[SELECT * FROM chainable LEFT JOIN x ON chainable.a = x.a]]>
     </Resource>
@@ -757,7 +1114,7 @@ MultipleInput(readOrder=[1,0], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testKeepMultipleInputWithOneMemberForChainableSource[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testKeepMultipleInputWithOneMemberForChainableSource[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[SELECT * FROM chainable LEFT JOIN x ON chainable.a = x.a]]>
     </Resource>
@@ -778,7 +1135,67 @@ MultipleInput(readOrder=[1,0], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testKeepUsefulUnion[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testKeepMultipleInputWithOneMemberForChainableSource[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[SELECT * FROM chainable LEFT JOIN x ON chainable.a = x.a]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], a0=[$1], b=[$2], c=[$3], nx=[$4])
++- LogicalJoin(condition=[=($0, $1)], joinType=[left])
+   :- LogicalTableScan(table=[[default_catalog, default_database, chainable]])
+   +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+MultipleInput(readOrder=[1,0], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = a0)], select=[a, a0, b, c, nx], build=[right])\n:- [#1] BoundedStreamScan(table=[[default_catalog, default_database, chainable]], fields=[a])\n+- [#2] Exchange(distribution=[broadcast])\n])
+:- BoundedStreamScan(table=[[default_catalog, default_database, chainable]], fields=[a])
++- Exchange(distribution=[broadcast])
+   +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testKeepUsefulUnion[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+WITH
+  T1 AS (SELECT chainable.a AS a FROM chainable LEFT JOIN x ON chainable.a = x.a),
+  T2 AS (SELECT chainable.a AS a FROM chainable LEFT JOIN y ON chainable.a = y.d)
+SELECT * FROM
+  (SELECT a FROM T1)
+  UNION ALL
+  (SELECT a FROM T2)
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalUnion(all=[true])
+:- LogicalProject(a=[$0])
+:  +- LogicalJoin(condition=[=($0, $1)], joinType=[left])
+:     :- LogicalTableScan(table=[[default_catalog, default_database, chainable]])
+:     +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
++- LogicalProject(a=[$0])
+   +- LogicalJoin(condition=[=($0, $1)], joinType=[left])
+      :- LogicalTableScan(table=[[default_catalog, default_database, chainable]])
+      +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+MultipleInput(readOrder=[1,0,1,0], members=[\nUnion(all=[true], union=[a])\n:- Calc(select=[a])\n:  +- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = a0)], select=[a, a0], build=[right])\n:     :- [#1] BoundedStreamScan(table=[[default_catalog, default_database, chainable]], fields=[a])\n:     +- [#2] Exchange(distribution=[broadcast])\n+- Calc(select=[a])\n   +- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, d], build=[right])\n      :- [#1] BoundedStreamScan [...]
+:- BoundedStreamScan(table=[[default_catalog, default_database, chainable]], fields=[a])(reuse_id=[1])
+:- Exchange(distribution=[broadcast])
+:  +- Calc(select=[a])
+:     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+:- Reused(reference_id=[1])
++- Exchange(distribution=[broadcast])
+   +- Calc(select=[d])
+      +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testKeepUsefulUnion[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -817,7 +1234,104 @@ MultipleInput(readOrder=[1,0,1,0], members=[\nUnion(all=[true], union=[a])\n:- C
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testManyMultipleInputs[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testManyMultipleInputs[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
+    <Resource name="sql">
+      <![CDATA[
+WITH
+  T1 AS (
+    SELECT a, ny, nz FROM x
+      LEFT JOIN y ON x.a = y.ny
+      LEFT JOIN z ON x.a = z.nz),
+  T2 AS (
+    SELECT T1.a AS a, t.b AS b, d, T1.ny AS ny, nz FROM T1
+      LEFT JOIN t ON T1.a = t.a
+      INNER JOIN y ON T1.a = y.d),
+  T3 AS (
+    SELECT T1.a AS a, t.b AS b, d, T1.ny AS ny, nz FROM T1
+      LEFT JOIN y ON T1.a = y.d
+      INNER JOIN t ON T1.a = t.a),
+  T4 AS (SELECT b, SUM(d) AS sd, SUM(ny) AS sy, SUM(nz) AS sz FROM T2 GROUP BY b),
+  T5 AS (SELECT b, SUM(d) AS sd, SUM(ny) AS sy, SUM(nz) AS sz FROM T3 GROUP BY b)
+SELECT * FROM
+  (SELECT t.b, sd, sy, sz FROM T4 LEFT JOIN t ON T4.b = t.b)
+  UNION ALL
+  (SELECT y.e, sd, sy, sz FROM T5 LEFT JOIN y ON T5.b = y.e)
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalUnion(all=[true])
+:- LogicalProject(b=[$5], sd=[$1], sy=[$2], sz=[$3])
+:  +- LogicalJoin(condition=[=($0, $5)], joinType=[left])
+:     :- LogicalAggregate(group=[{0}], sd=[SUM($1)], sy=[SUM($2)], sz=[SUM($3)])
+:     :  +- LogicalProject(b=[$4], d=[$6], ny=[$1], nz=[$2])
+:     :     +- LogicalJoin(condition=[=($0, $6)], joinType=[inner])
+:     :        :- LogicalJoin(condition=[=($0, $3)], joinType=[left])
+:     :        :  :- LogicalProject(a=[$0], ny=[$7], nz=[$11])
+:     :        :  :  +- LogicalJoin(condition=[=($0, $11)], joinType=[left])
+:     :        :  :     :- LogicalJoin(condition=[=($0, $7)], joinType=[left])
+:     :        :  :     :  :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+:     :        :  :     :  +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+:     :        :  :     +- LogicalTableScan(table=[[default_catalog, default_database, z, source: [TestTableSource(g, h, i, nz)]]])
+:     :        :  +- LogicalTableScan(table=[[default_catalog, default_database, t]])
+:     :        +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+:     +- LogicalTableScan(table=[[default_catalog, default_database, t]])
++- LogicalProject(e=[$5], sd=[$1], sy=[$2], sz=[$3])
+   +- LogicalJoin(condition=[=($0, $5)], joinType=[left])
+      :- LogicalAggregate(group=[{0}], sd=[SUM($1)], sy=[SUM($2)], sz=[SUM($3)])
+      :  +- LogicalProject(b=[$8], d=[$3], ny=[$1], nz=[$2])
+      :     +- LogicalJoin(condition=[=($0, $7)], joinType=[inner])
+      :        :- LogicalJoin(condition=[=($0, $3)], joinType=[left])
+      :        :  :- LogicalProject(a=[$0], ny=[$7], nz=[$11])
+      :        :  :  +- LogicalJoin(condition=[=($0, $11)], joinType=[left])
+      :        :  :     :- LogicalJoin(condition=[=($0, $7)], joinType=[left])
+      :        :  :     :  :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+      :        :  :     :  +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+      :        :  :     +- LogicalTableScan(table=[[default_catalog, default_database, z, source: [TestTableSource(g, h, i, nz)]]])
+      :        :  +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+      :        +- LogicalTableScan(table=[[default_catalog, default_database, t]])
+      +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+MultipleInput(readOrder=[0,0,1,1], members=[\nUnion(all=[true], union=[b, sd, sy, sz])\n:- Calc(select=[b0 AS b, sd, sy, sz])\n:  +- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(b = b0)], select=[b, sd, sy, sz, b0], build=[right])\n:     :- HashAggregate(isMerge=[true], groupBy=[b], select=[b, Final_SUM(sum$0) AS sd, Final_SUM(sum$1) AS sy, Final_SUM(sum$2) AS sz])\n:     :  +- [#3] Exchange(distribution=[hash[b]])\n:     +- [#1] Exchange(distribution=[broadcast])\n+- Calc(select=[e, [...]
+:- Exchange(distribution=[broadcast])
+:  +- Calc(select=[b])
+:     +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])(reuse_id=[1])
+:- Exchange(distribution=[broadcast])
+:  +- Calc(select=[e])
+:     +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+:- Exchange(distribution=[hash[b]])
+:  +- LocalHashAggregate(groupBy=[b], select=[b, Partial_SUM(d) AS sum$0, Partial_SUM(ny) AS sum$1, Partial_SUM(nz) AS sum$2])
+:     +- Calc(select=[b, d, ny, nz])
+:        +- MultipleInput(readOrder=[0,1,0], members=[\nNestedLoopJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, ny, nz, b, d], build=[right])\n:- Calc(select=[a, ny, nz, b])\n:  +- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = a0)], select=[a, ny, nz, a0, b], build=[right])\n:     :- [#2] MultipleInput(readOrder=[0,1,0], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = nz)], select=[a, ny, nz], build=[right])\n:- NestedLoopJoin(joinType=[LeftOuterJoin], whe [...]
+:           :- Exchange(distribution=[broadcast])(reuse_id=[4])
+:           :  +- Calc(select=[d])
+:           :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+:           :- MultipleInput(readOrder=[0,1,0], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = nz)], select=[a, ny, nz], build=[right])\n:- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = ny)], select=[a, ny], build=[right])\n:  :- [#2] Calc(select=[a])\n:  +- [#3] Exchange(distribution=[broadcast])\n+- [#1] Exchange(distribution=[broadcast])\n])(reuse_id=[3])
+:           :  :- Exchange(distribution=[broadcast])
+:           :  :  +- Calc(select=[nz])
+:           :  :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, z, source: [TestTableSource(g, h, i, nz)]]], fields=[g, h, i, nz])
+:           :  :- Calc(select=[a])
+:           :  :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+:           :  +- Exchange(distribution=[broadcast])
+:           :     +- Calc(select=[ny])
+:           :        +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+:           +- Exchange(distribution=[broadcast])(reuse_id=[2])
+:              +- Calc(select=[a, b])
+:                 +- Reused(reference_id=[1])
++- Exchange(distribution=[hash[b]])
+   +- LocalHashAggregate(groupBy=[b], select=[b, Partial_SUM(d) AS sum$0, Partial_SUM(ny) AS sum$1, Partial_SUM(nz) AS sum$2])
+      +- Calc(select=[b, d, ny, nz])
+         +- MultipleInput(readOrder=[0,1,0], members=[\nNestedLoopJoin(joinType=[InnerJoin], where=[(a = a0)], select=[a, ny, nz, d, a0, b], build=[right])\n:- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = d)], select=[a, ny, nz, d], build=[right])\n:  :- [#2] MultipleInput(readOrder=[0,1,0], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = nz)], select=[a, ny, nz], build=[right])\n:- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = ny)], select=[a, ny], build=[ [...]
+            :- Reused(reference_id=[2])
+            :- Reused(reference_id=[3])
+            +- Reused(reference_id=[4])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testManyMultipleInputs[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -914,7 +1428,7 @@ MultipleInput(readOrder=[0,0,1,1], members=[\nUnion(all=[true], union=[b, sd, sy
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testManyMultipleInputs[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testManyMultipleInputs[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -1011,7 +1525,7 @@ MultipleInput(readOrder=[0,0,1,1], members=[\nUnion(all=[true], union=[b, sd, sy
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testRelatedInputsWithAgg[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testRelatedInputsWithAgg[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -1060,7 +1574,7 @@ Calc(select=[a, b, a0, b0, c])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testKeepUsefulUnion[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testKeepUsefulUnion[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -1099,7 +1613,37 @@ MultipleInput(readOrder=[1,0,1,0], members=[\nUnion(all=[true], union=[a])\n:- C
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testNoPriorityConstraint[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testNoPriorityConstraint[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+SELECT * FROM x
+  INNER JOIN y ON x.a = y.d
+  INNER JOIN t ON x.a = t.a
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], b=[$1], c=[$2], nx=[$3], d=[$4], e=[$5], f=[$6], ny=[$7], a0=[$8], b0=[$9], c0=[$10])
++- LogicalJoin(condition=[=($0, $8)], joinType=[inner])
+   :- LogicalJoin(condition=[=($0, $4)], joinType=[inner])
+   :  :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+   :  +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+   +- LogicalTableScan(table=[[default_catalog, default_database, t]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+MultipleInput(members=[\nSortMergeJoin(joinType=[InnerJoin], where=[(a = a0)], select=[a, b, c, nx, d, e, f, ny, a0, b0, c0])\n:- SortMergeJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, c, nx, d, e, f, ny])\n:  :- [#2] Exchange(distribution=[hash[a]])\n:  +- [#3] Exchange(distribution=[hash[d]])\n+- [#1] Exchange(distribution=[hash[a]])\n])
+:- Exchange(distribution=[hash[a]])
+:  +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
+:- Exchange(distribution=[hash[a]])
+:  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
++- Exchange(distribution=[hash[d]])
+   +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testNoPriorityConstraint[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 SELECT * FROM x
@@ -1129,7 +1673,49 @@ MultipleInput(members=[\nSortMergeJoin(joinType=[InnerJoin], where=[(a = a0)], s
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testRelatedInputs[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testRelatedInputs[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+WITH
+  T1 AS (SELECT x.a AS a, y.d AS b FROM y LEFT JOIN x ON y.d = x.a),
+  T2 AS (
+    SELECT a, b FROM
+      (SELECT a, b FROM T1)
+      UNION ALL
+      (SELECT x.a AS a, x.b AS b FROM x))
+SELECT * FROM T2 LEFT JOIN t ON T2.a = t.a
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], b=[$1], a0=[$2], b0=[$3], c=[$4])
++- LogicalJoin(condition=[=($0, $2)], joinType=[left])
+   :- LogicalUnion(all=[true])
+   :  :- LogicalProject(a=[$4], b=[$0])
+   :  :  +- LogicalJoin(condition=[=($0, $4)], joinType=[left])
+   :  :     :- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+   :  :     +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+   :  +- LogicalProject(a=[$0], b=[$1])
+   :     +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+   +- LogicalTableScan(table=[[default_catalog, default_database, t]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+MultipleInput(readOrder=[0,1,2,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = a0)], select=[a, b, a0, b0, c], build=[right])\n:- Union(all=[true], union=[a, b])\n:  :- Calc(select=[a, CAST(d AS BIGINT) AS b])\n:  :  +- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(d = a)], select=[d, a], build=[right])\n:  :     :- [#3] Calc(select=[d])\n:  :     +- [#4] Exchange(distribution=[broadcast])\n:  +- [#2] Calc(select=[a, b])\n+- [#1] Exchange(distribution=[broadcast])\n])
+:- Exchange(distribution=[broadcast])
+:  +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
+:- Calc(select=[a, b])
+:  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])(reuse_id=[1])
+:- Calc(select=[d])
+:  +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
++- Exchange(distribution=[broadcast])
+   +- Calc(select=[a])
+      +- Reused(reference_id=[1])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testRelatedInputs[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -1171,7 +1757,7 @@ MultipleInput(readOrder=[0,1,2,1], members=[\nNestedLoopJoin(joinType=[LeftOuter
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testRemoveRedundantUnion[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testRemoveRedundantUnion[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -1239,7 +1825,7 @@ Union(all=[true], union=[cnt])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testRelatedInputs[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testRelatedInputs[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -1281,7 +1867,56 @@ MultipleInput(readOrder=[0,1,2,1], members=[\nNestedLoopJoin(joinType=[LeftOuter
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testRemoveOneInputOperatorFromRoot[shuffleMode: ALL_EXCHANGES_BLOCKING]">
+  <TestCase name="testRelatedInputsWithAgg[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+WITH
+  T1 AS (SELECT x.a AS a, y.d AS b FROM y LEFT JOIN x ON y.d = x.a),
+  T2 AS (
+    SELECT a, b FROM
+      (SELECT a, b FROM T1)
+      UNION ALL
+      (SELECT COUNT(x.a) AS a, x.b AS b FROM x GROUP BY x.b))
+SELECT * FROM T2 LEFT JOIN t ON T2.a = t.a
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalProject(a=[$0], b=[$1], a0=[$2], b0=[$3], c=[$4])
++- LogicalJoin(condition=[=($0, $5)], joinType=[left])
+   :- LogicalUnion(all=[true])
+   :  :- LogicalProject(a=[$4], b=[$0])
+   :  :  +- LogicalJoin(condition=[=($0, $4)], joinType=[left])
+   :  :     :- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+   :  :     +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+   :  +- LogicalProject(a=[$1], b=[$0])
+   :     +- LogicalAggregate(group=[{0}], a=[COUNT($1)])
+   :        +- LogicalProject(b=[$1], a=[$0])
+   :           +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+   +- LogicalProject(a=[$0], b=[$1], c=[$2], a0=[CAST($0):BIGINT])
+      +- LogicalTableScan(table=[[default_catalog, default_database, t]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+Calc(select=[a, b, a0, b0, c])
++- MultipleInput(readOrder=[0,2,1,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = a00)], select=[a, b, a0, b0, c, a00], build=[right])\n:- Union(all=[true], union=[a, b])\n:  :- Calc(select=[CAST(a AS BIGINT) AS a, CAST(d AS BIGINT) AS b])\n:  :  +- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(d = a)], select=[d, a], build=[right])\n:  :     :- [#2] Calc(select=[d])\n:  :     +- [#3] Exchange(distribution=[broadcast])\n:  +- Calc(select=[CAST(a AS BIGINT) AS a, b] [...]
+   :- Exchange(distribution=[broadcast])
+   :  +- Calc(select=[a, b, c, CAST(a AS BIGINT) AS a0])
+   :     +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
+   :- Calc(select=[d])
+   :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+   :- Exchange(distribution=[broadcast])
+   :  +- Calc(select=[a])
+   :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])(reuse_id=[1])
+   +- Exchange(distribution=[hash[b]])
+      +- LocalHashAggregate(groupBy=[b], select=[b, Partial_COUNT(a) AS count$0])
+         +- Calc(select=[b, a])
+            +- Reused(reference_id=[1])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testRemoveOneInputOperatorFromRoot[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: AdaptiveBatch]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -1335,7 +1970,7 @@ Union(all=[true], union=[a, b])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testRelatedInputsWithAgg[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testRelatedInputsWithAgg[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -1368,7 +2003,7 @@ LogicalProject(a=[$0], b=[$1], a0=[$2], b0=[$3], c=[$4])
     <Resource name="optimized exec plan">
       <![CDATA[
 Calc(select=[a, b, a0, b0, c])
-+- MultipleInput(readOrder=[0,2,1,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = a00)], select=[a, b, a0, b0, c, a00], build=[right])\n:- Union(all=[true], union=[a, b])\n:  :- Calc(select=[CAST(a AS BIGINT) AS a, CAST(d AS BIGINT) AS b])\n:  :  +- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(d = a)], select=[d, a], build=[right])\n:  :     :- [#2] Calc(select=[d])\n:  :     +- [#3] Exchange(distribution=[broadcast])\n:  +- Calc(select=[CAST(a AS BIGINT) AS a, b] [...]
++- MultipleInput(readOrder=[0,1,0,1], members=[\nNestedLoopJoin(joinType=[LeftOuterJoin], where=[(a = a00)], select=[a, b, a0, b0, c, a00], build=[right])\n:- Union(all=[true], union=[a, b])\n:  :- Calc(select=[CAST(a AS BIGINT) AS a, CAST(d AS BIGINT) AS b])\n:  :  +- NestedLoopJoin(joinType=[LeftOuterJoin], where=[(d = a)], select=[d, a], build=[right])\n:  :     :- [#2] Calc(select=[d])\n:  :     +- [#3] Exchange(distribution=[broadcast])\n:  +- Calc(select=[CAST(a AS BIGINT) AS a, b] [...]
    :- Exchange(distribution=[broadcast])
    :  +- Calc(select=[a, b, c, CAST(a AS BIGINT) AS a0])
    :     +- BoundedStreamScan(table=[[default_catalog, default_database, t]], fields=[a, b, c])
@@ -1384,7 +2019,61 @@ Calc(select=[a, b, a0, b0, c])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testRemoveRedundantUnion[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testRemoveOneInputOperatorFromRoot[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+WITH
+  T1 AS (SELECT a FROM x INNER JOIN y ON x.a = y.d),
+  T2 AS (SELECT b FROM x INNER JOIN y ON x.b = y.e)
+SELECT * FROM
+  (SELECT a, b FROM T1 LEFT JOIN T2 ON T1.a = T2.b)
+  UNION ALL
+  (SELECT a, b FROM x)
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalUnion(all=[true])
+:- LogicalProject(a=[$0], b=[$2])
+:  +- LogicalJoin(condition=[=($1, $2)], joinType=[left])
+:     :- LogicalProject(a=[$0], a0=[CAST($0):BIGINT])
+:     :  +- LogicalJoin(condition=[=($0, $4)], joinType=[inner])
+:     :     :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+:     :     +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+:     +- LogicalProject(b=[$1])
+:        +- LogicalJoin(condition=[=($1, $5)], joinType=[inner])
+:           :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+:           +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
++- LogicalProject(a=[$0], b=[$1])
+   +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+Union(all=[true], union=[a, b])
+:- Calc(select=[a, b])
+:  +- MultipleInput(readOrder=[2,1,0], members=[\nHashJoin(joinType=[LeftOuterJoin], where=[(a0 = b)], select=[a, a0, b], build=[right])\n:- [#1] Exchange(distribution=[hash[a0]])\n+- Calc(select=[b])\n   +- HashJoin(joinType=[InnerJoin], where=[(b = e)], select=[b, e], build=[right])\n      :- [#2] Exchange(distribution=[hash[b]])\n      +- [#3] Exchange(distribution=[hash[e]])\n])
+:     :- Exchange(distribution=[hash[a0]])
+:     :  +- Calc(select=[a, CAST(a AS BIGINT) AS a0])
+:     :     +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[right])
+:     :        :- Exchange(distribution=[hash[a]])
+:     :        :  +- Calc(select=[a])
+:     :        :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+:     :        +- Exchange(distribution=[hash[d]])
+:     :           +- Calc(select=[d])
+:     :              +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
+:     :- Exchange(distribution=[hash[b]])
+:     :  +- Calc(select=[b])
+:     :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+:     +- Exchange(distribution=[hash[e]])
+:        +- Calc(select=[e])
+:           +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
++- Calc(select=[a, b])
+   +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testRemoveRedundantUnion[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -1452,7 +2141,7 @@ Union(all=[true], union=[cnt])
 ]]>
     </Resource>
   </TestCase>
-  <TestCase name="testRemoveOneInputOperatorFromRoot[shuffleMode: ALL_EXCHANGES_PIPELINED]">
+  <TestCase name="testRemoveOneInputOperatorFromRoot[shuffleMode: ALL_EXCHANGES_BLOCKING, schedulerType: Default]">
     <Resource name="sql">
       <![CDATA[
 WITH
@@ -1503,6 +2192,74 @@ Union(all=[true], union=[a, b])
 :           +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
 +- Calc(select=[a, b])
    +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testRemoveRedundantUnion[shuffleMode: ALL_EXCHANGES_PIPELINED, schedulerType: Default]">
+    <Resource name="sql">
+      <![CDATA[
+WITH
+  T1 AS (SELECT COUNT(*) AS cnt FROM x GROUP BY a),
+  T2 AS (SELECT COUNT(*) AS cnt FROM y GROUP BY d),
+  T3 AS (SELECT a AS cnt FROM x INNER JOIN y ON x.a = y.d),
+  T4 AS (SELECT b AS cnt FROM x INNER JOIN y ON x.b = y.e)
+SELECT cnt FROM
+  (SELECT cnt FROM (SELECT cnt FROM T1) UNION ALL (SELECT cnt FROM T2))
+  UNION ALL
+  (SELECT cnt FROM (SELECT cnt FROM T3) UNION ALL (SELECT cnt FROM T4))
+]]>
+    </Resource>
+    <Resource name="ast">
+      <![CDATA[
+LogicalUnion(all=[true])
+:- LogicalProject(cnt=[$0])
+:  +- LogicalUnion(all=[true])
+:     :- LogicalProject(cnt=[$1])
+:     :  +- LogicalAggregate(group=[{0}], cnt=[COUNT()])
+:     :     +- LogicalProject(a=[$0])
+:     :        +- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+:     +- LogicalProject(cnt=[$1])
+:        +- LogicalAggregate(group=[{0}], cnt=[COUNT()])
+:           +- LogicalProject(d=[$0])
+:              +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
++- LogicalUnion(all=[true])
+   :- LogicalProject(cnt=[$0])
+   :  +- LogicalJoin(condition=[=($0, $4)], joinType=[inner])
+   :     :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+   :     +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+   +- LogicalProject(cnt=[$1])
+      +- LogicalJoin(condition=[=($1, $5)], joinType=[inner])
+         :- LogicalTableScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]])
+         +- LogicalTableScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]])
+]]>
+    </Resource>
+    <Resource name="optimized exec plan">
+      <![CDATA[
+Union(all=[true], union=[cnt])
+:- Union(all=[true], union=[cnt])
+:  :- Calc(select=[CAST(cnt AS BIGINT) AS cnt])
+:  :  +- HashAggregate(isMerge=[true], groupBy=[a], select=[a, Final_COUNT(count1$0) AS cnt])
+:  :     +- Exchange(distribution=[hash[a]])
+:  :        +- LocalHashAggregate(groupBy=[a], select=[a, Partial_COUNT(*) AS count1$0])
+:  :           +- Calc(select=[a])(reuse_id=[1])
+:  :              +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+:  +- Calc(select=[CAST(cnt AS BIGINT) AS cnt])
+:     +- HashAggregate(isMerge=[true], groupBy=[d], select=[d, Final_COUNT(count1$0) AS cnt])
+:        +- Exchange(distribution=[hash[d]])
+:           +- LocalHashAggregate(groupBy=[d], select=[d, Partial_COUNT(*) AS count1$0])
+:              +- Calc(select=[d])(reuse_id=[2])
+:                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
++- MultipleInput(readOrder=[1,0,1,0], members=[\nUnion(all=[true], union=[cnt])\n:- Calc(select=[CAST(a AS BIGINT) AS cnt])\n:  +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, d], build=[right])\n:     :- [#1] Exchange(distribution=[hash[a]])\n:     +- [#2] Exchange(distribution=[hash[d]])\n+- Calc(select=[b AS cnt])\n   +- HashJoin(joinType=[InnerJoin], where=[(b = e)], select=[b, e], build=[right])\n      :- [#3] Exchange(distribution=[hash[b]])\n      +- [#4] Exchange(di [...]
+   :- Exchange(distribution=[hash[a]])
+   :  +- Reused(reference_id=[1])
+   :- Exchange(distribution=[hash[d]])
+   :  +- Reused(reference_id=[2])
+   :- Exchange(distribution=[hash[b]])
+   :  +- Calc(select=[b])
+   :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c, nx)]]], fields=[a, b, c, nx])
+   +- Exchange(distribution=[hash[e]])
+      +- Calc(select=[e])
+         +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f, ny)]]], fields=[d, e, f, ny])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RankTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RankTest.xml
index 310aba81332..58dbad5526a 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RankTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RankTest.xml
@@ -36,11 +36,12 @@ LogicalSink(table=[default_catalog.default_database.sink], fields=[name, eat, cn
 Sink(table=[default_catalog.default_database.sink], fields=[name, eat, cnt])
 +- Calc(select=[name, eat, cnt], where=[(w0$o0 <= 3)])
    +- OverAggregate(partitionBy=[name], orderBy=[cnt DESC], window#0=[ROW_NUMBER(*) AS w0$o0 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[name, eat, cnt, w0$o0])
-      +- Sort(orderBy=[name ASC, cnt DESC])
-         +- Exchange(distribution=[hash[name]])
-            +- HashAggregate(isMerge=[true], groupBy=[name, eat], select=[name, eat, Final_SUM(sum$0) AS cnt])
-               +- Exchange(distribution=[hash[name, eat]])
-                  +- TableSourceScan(table=[[default_catalog, default_database, test_source, aggregates=[grouping=[name,eat], aggFunctions=[LongSumAggFunction(age)]]]], fields=[name, eat, sum$0])
+      +- Exchange(distribution=[forward])
+         +- Sort(orderBy=[name ASC, cnt DESC])
+            +- Exchange(distribution=[hash[name]])
+               +- HashAggregate(isMerge=[true], groupBy=[name, eat], select=[name, eat, Final_SUM(sum$0) AS cnt])
+                  +- Exchange(distribution=[hash[name, eat]])
+                     +- TableSourceScan(table=[[default_catalog, default_database, test_source, aggregates=[grouping=[name,eat], aggFunctions=[LongSumAggFunction(age)]]]], fields=[name, eat, sum$0])
 ]]>
     </Resource>
   </TestCase>
@@ -63,12 +64,14 @@ LogicalProject(a=[$0], b=[$1], rk=[$2])
     <Resource name="optimized exec plan">
       <![CDATA[
 Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[b], orderBy=[a ASC], global=[true], select=[a, b, w0$o0])
-+- Sort(orderBy=[b ASC, a ASC])
-   +- Exchange(distribution=[hash[b]])
-      +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[b], orderBy=[a ASC], global=[false], select=[a, b])
-         +- Sort(orderBy=[b ASC, a ASC])
-            +- Calc(select=[a, b])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, rk)]]], fields=[a, b, rk])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[b ASC, a ASC])
+      +- Exchange(distribution=[hash[b]])
+         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[b], orderBy=[a ASC], global=[false], select=[a, b])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[b ASC, a ASC])
+                  +- Calc(select=[a, b])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, rk)]]], fields=[a, b, rk])
 ]]>
     </Resource>
   </TestCase>
@@ -94,12 +97,14 @@ LogicalProject(a=[$0], b=[$1], rk1=[$2], rk2=[$3])
       <![CDATA[
 Calc(select=[a, b, w0$o0 AS rk1, w0$o0 AS rk2])
 +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[b], orderBy=[a ASC], global=[true], select=[a, b, w0$o0])
-   +- Sort(orderBy=[b ASC, a ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[b], orderBy=[a ASC], global=[false], select=[a, b])
-            +- Sort(orderBy=[b ASC, a ASC])
-               +- Calc(select=[a, b])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, a ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[b], orderBy=[a ASC], global=[false], select=[a, b])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[b ASC, a ASC])
+                     +- Calc(select=[a, b])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -123,11 +128,13 @@ LogicalProject(a=[$0], rk=[$1], b=[$2], c=[$3])
       <![CDATA[
 Calc(select=[a, w0$o0 AS rk, b, c])
 +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[a], orderBy=[a ASC], global=[true], select=[a, b, c, w0$o0])
-   +- Sort(orderBy=[a ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[a], orderBy=[a ASC], global=[false], select=[a, b, c])
-            +- Sort(orderBy=[a ASC])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[a], orderBy=[a ASC], global=[false], select=[a, b, c])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[a ASC])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -151,11 +158,13 @@ LogicalProject(a=[$0], b=[$1], rk=[$2])
       <![CDATA[
 Calc(select=[a, b, 2 AS $2])
 +- Rank(rankType=[RANK], rankRange=[rankStart=2, rankEnd=2], partitionBy=[b], orderBy=[a ASC, c ASC], global=[true], select=[a, b, c])
-   +- Sort(orderBy=[b ASC, a ASC, c ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=2], partitionBy=[b], orderBy=[a ASC, c ASC], global=[false], select=[a, b, c])
-            +- Sort(orderBy=[b ASC, a ASC, c ASC])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, a ASC, c ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=2], partitionBy=[b], orderBy=[a ASC, c ASC], global=[false], select=[a, b, c])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[b ASC, a ASC, c ASC])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -179,11 +188,13 @@ LogicalProject(a=[$0], b=[$1], rk=[$2])
       <![CDATA[
 Calc(select=[a, b, w0$o0])
 +- Rank(rankType=[RANK], rankRange=[rankStart=-1, rankEnd=2], partitionBy=[b, c], orderBy=[a ASC], global=[true], select=[a, b, c, w0$o0])
-   +- Sort(orderBy=[b ASC, c ASC, a ASC])
-      +- Exchange(distribution=[hash[b, c]])
-         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=2], partitionBy=[b, c], orderBy=[a ASC], global=[false], select=[a, b, c])
-            +- Sort(orderBy=[b ASC, c ASC, a ASC])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, c ASC, a ASC])
+         +- Exchange(distribution=[hash[b, c]])
+            +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=2], partitionBy=[b, c], orderBy=[a ASC], global=[false], select=[a, b, c])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[b ASC, c ASC, a ASC])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -207,12 +218,14 @@ LogicalProject(a=[$0], b=[$1], rk=[$2])
       <![CDATA[
 Calc(select=[a, b, w0$o0], where=[(a > 10)])
 +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=2], partitionBy=[b], orderBy=[a ASC], global=[true], select=[a, b, w0$o0])
-   +- Sort(orderBy=[b ASC, a ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=2], partitionBy=[b], orderBy=[a ASC], global=[false], select=[a, b])
-            +- Sort(orderBy=[b ASC, a ASC])
-               +- Calc(select=[a, b])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, a ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=2], partitionBy=[b], orderBy=[a ASC], global=[false], select=[a, b])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[b ASC, a ASC])
+                     +- Calc(select=[a, b])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -238,9 +251,10 @@ Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[], orderB
 +- Sort(orderBy=[a ASC])
    +- Exchange(distribution=[single])
       +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=9], partitionBy=[], orderBy=[a ASC], global=[false], select=[a, b])
-         +- Sort(orderBy=[a ASC])
-            +- Calc(select=[a, b])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[a ASC])
+               +- Calc(select=[a, b])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -272,13 +286,15 @@ LogicalProject(rn1=[CAST($3):INTEGER NOT NULL], rn2=[CAST($4):INTEGER NOT NULL])
       <![CDATA[
 Calc(select=[CAST(rna AS INTEGER) AS rn1, CAST(w0$o0 AS INTEGER) AS rn2], where=[(w0$o0 <= 200)])
 +- OverAggregate(partitionBy=[a], orderBy=[b DESC], window#0=[ROW_NUMBER(*) AS w0$o0_0 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o0_0])
-   +- Sort(orderBy=[a ASC, b DESC])
-      +- Exchange(distribution=[hash[a]])
-         +- Calc(select=[a, b, c, w0$o0], where=[(w0$o0 <= 100)])
-            +- OverAggregate(partitionBy=[a, c], orderBy=[b DESC], window#0=[ROW_NUMBER(*) AS w0$o0 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0])
-               +- Sort(orderBy=[a ASC, c ASC, b DESC])
-                  +- Exchange(distribution=[hash[a, c]])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, b DESC])
+         +- Exchange(distribution=[hash[a]])
+            +- Calc(select=[a, b, c, w0$o0], where=[(w0$o0 <= 100)])
+               +- OverAggregate(partitionBy=[a, c], orderBy=[b DESC], window#0=[ROW_NUMBER(*) AS w0$o0 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0])
+                  +- Exchange(distribution=[forward])
+                     +- Sort(orderBy=[a ASC, c ASC, b DESC])
+                        +- Exchange(distribution=[hash[a, c]])
+                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -342,17 +358,21 @@ LogicalProject(url=[CONCAT(_UTF-16LE'http://txmov2.a.yximgs.com', $0)], download
       <![CDATA[
 Calc(select=[CONCAT('http://txmov2.a.yximgs.com', uri) AS url, reqcount AS download_count, start_time AS timestamp])
 +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=100000], partitionBy=[start_time], orderBy=[reqcount DESC], global=[true], select=[uri, reqcount, start_time])
-   +- Sort(orderBy=[start_time ASC, reqcount DESC])
-      +- Exchange(distribution=[hash[start_time]])
-         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=100000], partitionBy=[start_time], orderBy=[reqcount DESC], global=[false], select=[uri, reqcount, start_time])
-            +- Sort(orderBy=[start_time ASC, reqcount DESC])
-               +- Calc(select=[uri, reqcount, start_time])
-                  +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=100000], partitionBy=[start_time, bucket_id], orderBy=[reqcount DESC], global=[true], select=[uri, reqcount, start_time, bucket_id])
-                     +- Sort(orderBy=[start_time ASC, bucket_id ASC, reqcount DESC])
-                        +- Exchange(distribution=[hash[start_time, bucket_id]])
-                           +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=100000], partitionBy=[start_time, bucket_id], orderBy=[reqcount DESC], global=[false], select=[uri, reqcount, start_time, bucket_id])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[start_time ASC, reqcount DESC])
+         +- Exchange(distribution=[hash[start_time]])
+            +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=100000], partitionBy=[start_time], orderBy=[reqcount DESC], global=[false], select=[uri, reqcount, start_time])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[start_time ASC, reqcount DESC])
+                     +- Calc(select=[uri, reqcount, start_time])
+                        +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=100000], partitionBy=[start_time, bucket_id], orderBy=[reqcount DESC], global=[true], select=[uri, reqcount, start_time, bucket_id])
+                           +- Exchange(distribution=[forward])
                               +- Sort(orderBy=[start_time ASC, bucket_id ASC, reqcount DESC])
-                                 +- BoundedStreamScan(table=[[default_catalog, default_database, MyTable1]], fields=[uri, reqcount, start_time, bucket_id])
+                                 +- Exchange(distribution=[hash[start_time, bucket_id]])
+                                    +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=100000], partitionBy=[start_time, bucket_id], orderBy=[reqcount DESC], global=[false], select=[uri, reqcount, start_time, bucket_id])
+                                       +- Exchange(distribution=[forward])
+                                          +- Sort(orderBy=[start_time ASC, bucket_id ASC, reqcount DESC])
+                                             +- BoundedStreamScan(table=[[default_catalog, default_database, MyTable1]], fields=[uri, reqcount, start_time, bucket_id])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RemoveCollationTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RemoveCollationTest.xml
index 001f01f15ff..6f394a947c8 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RemoveCollationTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RemoveCollationTest.xml
@@ -38,14 +38,16 @@ LogicalProject(EXPR$0=[$1])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortAggregate(isMerge=[false], groupBy=[a], select=[a, SUM(b) AS EXPR$0])
-   +- Calc(select=[a, b])
-      +- SortMergeJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d])
-         :- Exchange(distribution=[hash[a]])
-         :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
-         :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-         +- Exchange(distribution=[hash[d]])
-            +- Calc(select=[d])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+   +- Exchange(distribution=[forward])
+      +- Calc(select=[a, b])
+         +- Exchange(distribution=[forward])
+            +- SortMergeJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d])
+               :- Exchange(distribution=[hash[a]])
+               :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
+               :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+               +- Exchange(distribution=[hash[d]])
+                  +- Calc(select=[d])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -71,14 +73,16 @@ LogicalProject(EXPR$0=[$1])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortAggregate(isMerge=[false], groupBy=[d], select=[d, SUM(b) AS EXPR$0])
-   +- Calc(select=[d, b])
-      +- SortMergeJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d])
-         :- Exchange(distribution=[hash[a]])
-         :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
-         :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-         +- Exchange(distribution=[hash[d]])
-            +- Calc(select=[d])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+   +- Exchange(distribution=[forward])
+      +- Calc(select=[d, b])
+         +- Exchange(distribution=[forward])
+            +- SortMergeJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d])
+               :- Exchange(distribution=[hash[a]])
+               :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
+               :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+               +- Exchange(distribution=[hash[d]])
+                  +- Calc(select=[d])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -99,11 +103,13 @@ LogicalAggregate(group=[{0, 1}], cnt=[COUNT($2)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[true], groupBy=[a, b], select=[a, b, Final_COUNT(count$0) AS cnt])
-+- Sort(orderBy=[a ASC, b ASC])
-   +- Exchange(distribution=[hash[a, b]])
-      +- LocalSortAggregate(groupBy=[a, b], select=[a, b, Partial_COUNT(c) AS count$0])
-         +- Sort(orderBy=[a ASC, b ASC])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC, b ASC])
+      +- Exchange(distribution=[hash[a, b]])
+         +- LocalSortAggregate(groupBy=[a, b], select=[a, b, Partial_COUNT(c) AS count$0])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC, b ASC])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -136,9 +142,10 @@ MultipleInput(members=[\nSortMergeJoin(joinType=[InnerJoin], where=[(c = f)], se
 :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 +- Exchange(distribution=[hash[f]])
    +- LocalSortAggregate(groupBy=[f], select=[f, Partial_COUNT(f) AS count$0])
-      +- Sort(orderBy=[f ASC])
-         +- Calc(select=[f])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+      +- Exchange(distribution=[forward])
+         +- Sort(orderBy=[f ASC])
+            +- Calc(select=[f])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -171,9 +178,10 @@ MultipleInput(members=[\nSortMergeJoin(joinType=[InnerJoin], where=[(c = f)], se
 :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 +- Exchange(distribution=[hash[f]])
    +- LocalSortAggregate(groupBy=[f], select=[f, Partial_COUNT(f) AS count$0])
-      +- Sort(orderBy=[f ASC])
-         +- Calc(select=[f], where=[LIKE(f, '%llo%')])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+      +- Exchange(distribution=[forward])
+         +- Sort(orderBy=[f ASC])
+            +- Calc(select=[f], where=[LIKE(f, '%llo%')])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -208,12 +216,14 @@ SortMergeJoin(joinType=[InnerJoin], where=[(c = f1)], select=[a, b, c, f1])
    +- Calc(select=[f0 AS f1])
       +- Correlate(invocation=[split($cor0.f)], correlate=[table(split($cor0.f))], select=[f,cnt,f0], rowType=[RecordType(VARCHAR(2147483647) f, BIGINT cnt, VARCHAR(2147483647) f0)], joinType=[INNER])
          +- SortAggregate(isMerge=[true], groupBy=[f], select=[f, Final_COUNT(count$0) AS cnt])
-            +- Sort(orderBy=[f ASC])
-               +- Exchange(distribution=[hash[f]])
-                  +- LocalSortAggregate(groupBy=[f], select=[f, Partial_COUNT(f) AS count$0])
-                     +- Sort(orderBy=[f ASC])
-                        +- Calc(select=[f])
-                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[f ASC])
+                  +- Exchange(distribution=[hash[f]])
+                     +- LocalSortAggregate(groupBy=[f], select=[f, Partial_COUNT(f) AS count$0])
+                        +- Exchange(distribution=[forward])
+                           +- Sort(orderBy=[f ASC])
+                              +- Calc(select=[f])
+                                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -370,26 +380,28 @@ Calc(select=[id, tb2_ids, tb3_ids, name, tb2_names, tb3_names, name0, name1])
    :        :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, tb1, source: [TestTableSource(id, key, tb2_ids, tb3_ids, name)]]], fields=[id, key, tb2_ids, tb3_ids, name])(reuse_id=[1])
    :        :- Exchange(distribution=[hash[tb1_id]])
    :        :  +- LocalSortAggregate(groupBy=[tb1_id], select=[tb1_id, Partial_LISTAGG(tb3_name, $f2) AS (accDelimiter$0, concatAcc$1)])
-   :        :     +- Sort(orderBy=[tb1_id ASC])
-   :        :        +- Calc(select=[id AS tb1_id, name AS tb3_name, ',' AS $f2])
-   :        :           +- SortMergeJoin(joinType=[LeftOuterJoin], where=[(tb3_id = id0)], select=[id, tb3_id, id0, name])
-   :        :              :- Exchange(distribution=[hash[tb3_id]])
-   :        :              :  +- Calc(select=[id, f0 AS tb3_id])
-   :        :              :     +- Correlate(invocation=[split($cor1.tb3_ids)], correlate=[table(split($cor1.tb3_ids))], select=[id,key,tb2_ids,tb3_ids,name,f0], rowType=[RecordType(VARCHAR(2147483647) id, VARCHAR(2147483647) key, VARCHAR(2147483647) tb2_ids, VARCHAR(2147483647) tb3_ids, VARCHAR(2147483647) name, VARCHAR(2147483647) f0)], joinType=[INNER])
-   :        :              :        +- Reused(reference_id=[1])
-   :        :              +- Exchange(distribution=[hash[id]])
-   :        :                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, tb3, source: [TestTableSource(id, name)]]], fields=[id, name])
+   :        :     +- Exchange(distribution=[forward])
+   :        :        +- Sort(orderBy=[tb1_id ASC])
+   :        :           +- Calc(select=[id AS tb1_id, name AS tb3_name, ',' AS $f2])
+   :        :              +- SortMergeJoin(joinType=[LeftOuterJoin], where=[(tb3_id = id0)], select=[id, tb3_id, id0, name])
+   :        :                 :- Exchange(distribution=[hash[tb3_id]])
+   :        :                 :  +- Calc(select=[id, f0 AS tb3_id])
+   :        :                 :     +- Correlate(invocation=[split($cor1.tb3_ids)], correlate=[table(split($cor1.tb3_ids))], select=[id,key,tb2_ids,tb3_ids,name,f0], rowType=[RecordType(VARCHAR(2147483647) id, VARCHAR(2147483647) key, VARCHAR(2147483647) tb2_ids, VARCHAR(2147483647) tb3_ids, VARCHAR(2147483647) name, VARCHAR(2147483647) f0)], joinType=[INNER])
+   :        :                 :        +- Reused(reference_id=[1])
+   :        :                 +- Exchange(distribution=[hash[id]])
+   :        :                    +- LegacyTableSourceScan(table=[[default_catalog, default_database, tb3, source: [TestTableSource(id, name)]]], fields=[id, name])
    :        +- Exchange(distribution=[hash[tb1_id]])
    :           +- LocalSortAggregate(groupBy=[tb1_id], select=[tb1_id, Partial_LISTAGG(tb2_name, $f2) AS (accDelimiter$0, concatAcc$1)])
-   :              +- Sort(orderBy=[tb1_id ASC])
-   :                 +- Calc(select=[id AS tb1_id, name AS tb2_name, ',' AS $f2])
-   :                    +- SortMergeJoin(joinType=[LeftOuterJoin], where=[(tb2_id = id0)], select=[id, tb2_id, id0, name])
-   :                       :- Exchange(distribution=[hash[tb2_id]])
-   :                       :  +- Calc(select=[id, f0 AS tb2_id])
-   :                       :     +- Correlate(invocation=[split($cor0.tb2_ids)], correlate=[table(split($cor0.tb2_ids))], select=[id,key,tb2_ids,tb3_ids,name,f0], rowType=[RecordType(VARCHAR(2147483647) id, VARCHAR(2147483647) key, VARCHAR(2147483647) tb2_ids, VARCHAR(2147483647) tb3_ids, VARCHAR(2147483647) name, VARCHAR(2147483647) f0)], joinType=[INNER])
-   :                       :        +- Reused(reference_id=[1])
-   :                       +- Exchange(distribution=[hash[id]])
-   :                          +- LegacyTableSourceScan(table=[[default_catalog, default_database, tb2, source: [TestTableSource(id, name)]]], fields=[id, name])
+   :              +- Exchange(distribution=[forward])
+   :                 +- Sort(orderBy=[tb1_id ASC])
+   :                    +- Calc(select=[id AS tb1_id, name AS tb2_name, ',' AS $f2])
+   :                       +- SortMergeJoin(joinType=[LeftOuterJoin], where=[(tb2_id = id0)], select=[id, tb2_id, id0, name])
+   :                          :- Exchange(distribution=[hash[tb2_id]])
+   :                          :  +- Calc(select=[id, f0 AS tb2_id])
+   :                          :     +- Correlate(invocation=[split($cor0.tb2_ids)], correlate=[table(split($cor0.tb2_ids))], select=[id,key,tb2_ids,tb3_ids,name,f0], rowType=[RecordType(VARCHAR(2147483647) id, VARCHAR(2147483647) key, VARCHAR(2147483647) tb2_ids, VARCHAR(2147483647) tb3_ids, VARCHAR(2147483647) name, VARCHAR(2147483647) f0)], joinType=[INNER])
+   :                          :        +- Reused(reference_id=[1])
+   :                          +- Exchange(distribution=[hash[id]])
+   :                             +- LegacyTableSourceScan(table=[[default_catalog, default_database, tb2, source: [TestTableSource(id, name)]]], fields=[id, name])
    +- Exchange(distribution=[hash[id]])
       +- LegacyTableSourceScan(table=[[default_catalog, default_database, tb4, source: [TestTableSource(id, name)]]], fields=[id, name])
 ]]>
@@ -488,13 +500,16 @@ LogicalProject(sum_b=[$1], avg_b=[/(CASE(>(COUNT($1) OVER (PARTITION BY $0 ORDER
       <![CDATA[
 Calc(select=[sum_b, (CASE((w0$o0 > 0), w0$o1, null:BIGINT) / w0$o0) AS avg_b, w0$o2 AS rn])
 +- OverAggregate(partitionBy=[a], orderBy=[a ASC], window#0=[COUNT(sum_b) AS w0$o0, $SUM0(sum_b) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#1=[RANK(*) AS w0$o2 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, sum_b, w0$o0, w0$o1, w0$o2])
-   +- SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS sum_b])
-      +- Sort(orderBy=[a ASC])
-         +- Exchange(distribution=[hash[a]])
-            +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0])
-               +- Sort(orderBy=[a ASC])
-                  +- Calc(select=[a, b])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS sum_b])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[a ASC])
+               +- Exchange(distribution=[hash[a]])
+                  +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0])
+                     +- Exchange(distribution=[forward])
+                        +- Sort(orderBy=[a ASC])
+                           +- Calc(select=[a, b])
+                              +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -546,13 +561,16 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($1)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[a], select=[a, SUM(b) AS EXPR$1])
-+- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[true], select=[a, b])
-   +- Sort(orderBy=[a ASC, b ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[false], select=[a, b])
-            +- Sort(orderBy=[a ASC, b ASC])
-               +- Calc(select=[a, b])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[true], select=[a, b])
+      +- Exchange(distribution=[forward])
+         +- Sort(orderBy=[a ASC, b ASC])
+            +- Exchange(distribution=[hash[a]])
+               +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[false], select=[a, b])
+                  +- Exchange(distribution=[forward])
+                     +- Sort(orderBy=[a ASC, b ASC])
+                        +- Calc(select=[a, b])
+                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -578,12 +596,15 @@ LogicalAggregate(group=[{0, 1}], EXPR$2=[MAX($2)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[a, b], select=[a, b, MAX(c) AS EXPR$2])
-+- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[true], select=[a, b, c])
-   +- Sort(orderBy=[a ASC, b ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[false], select=[a, b, c])
-            +- Sort(orderBy=[a ASC, b ASC])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[true], select=[a, b, c])
+      +- Exchange(distribution=[forward])
+         +- Sort(orderBy=[a ASC, b ASC])
+            +- Exchange(distribution=[hash[a]])
+               +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[false], select=[a, b, c])
+                  +- Exchange(distribution=[forward])
+                     +- Sort(orderBy=[a ASC, b ASC])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -608,11 +629,13 @@ LogicalProject(a=[$0], b=[$1], c=[$2], rk=[$3])
     <Resource name="optimized exec plan">
       <![CDATA[
 Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[true], select=[a, b, c, w0$o0])
-+- Sort(orderBy=[a ASC, b ASC])
-   +- Exchange(distribution=[hash[a]])
-      +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[false], select=[a, b, c])
-         +- Sort(orderBy=[a ASC, b ASC])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC, b ASC])
+      +- Exchange(distribution=[hash[a]])
+         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[false], select=[a, b, c])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC, b ASC])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -639,13 +662,16 @@ LogicalProject(a=[$0], c=[$1], rk=[$2])
     <Resource name="optimized exec plan">
       <![CDATA[
 Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[a ASC], global=[true], select=[a, c, w0$o0])
-+- SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_COUNT(count$0) AS c])
-   +- Sort(orderBy=[a ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- LocalSortAggregate(groupBy=[a], select=[a, Partial_COUNT(c) AS count$0])
-            +- Sort(orderBy=[a ASC])
-               +- Calc(select=[a, c])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_COUNT(count$0) AS c])
+      +- Exchange(distribution=[forward])
+         +- Sort(orderBy=[a ASC])
+            +- Exchange(distribution=[hash[a]])
+               +- LocalSortAggregate(groupBy=[a], select=[a, Partial_COUNT(c) AS count$0])
+                  +- Exchange(distribution=[forward])
+                     +- Sort(orderBy=[a ASC])
+                        +- Calc(select=[a, c])
+                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -675,9 +701,10 @@ SortAggregate(isMerge=[false], select=[COUNT(a) AS EXPR$0, SUM(b) AS EXPR$1])
    +- Sort(orderBy=[b ASC])
       +- Exchange(distribution=[single])
          +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[], orderBy=[b ASC], global=[false], select=[a, b])
-            +- Sort(orderBy=[b ASC])
-               +- Calc(select=[a, b])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[b ASC])
+                  +- Calc(select=[a, b])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RemoveShuffleTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RemoveShuffleTest.xml
index e14af153cfb..f0ad7df8cfe 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RemoveShuffleTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/RemoveShuffleTest.xml
@@ -37,11 +37,13 @@ LogicalProject(EXPR$0=[$1])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- HashAggregate(isMerge=[false], groupBy=[c], select=[c, COUNT(*) AS EXPR$0])
-   +- Calc(select=[c])
-      +- HashAggregate(isMerge=[true], groupBy=[a, c], select=[a, c])
-         +- Exchange(distribution=[hash[c]])
-            +- LocalHashAggregate(groupBy=[a, c], select=[a, c])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[keep_input_as_is[hash[c]]])
+      +- Calc(select=[c])
+         +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+            +- HashAggregate(isMerge=[true], groupBy=[a, c], select=[a, c])
+               +- Exchange(distribution=[hash[c]])
+                  +- LocalHashAggregate(groupBy=[a, c], select=[a, c])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -213,14 +215,16 @@ LogicalProject(EXPR$0=[$1])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- HashAggregate(isMerge=[false], groupBy=[a], select=[a, SUM(b) AS EXPR$0])
-   +- Calc(select=[a, b])
-      +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
-         :- Exchange(distribution=[hash[a]])
-         :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
-         :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-         +- Exchange(distribution=[hash[d]])
-            +- Calc(select=[d])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+   +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+      +- Calc(select=[a, b])
+         +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+            +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
+               :- Exchange(distribution=[hash[a]])
+               :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
+               :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+               +- Exchange(distribution=[hash[d]])
+                  +- Calc(select=[d])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -246,13 +250,14 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- HashAggregate(isMerge=[false], groupBy=[a, d], select=[a, d, SUM(b) AS EXPR$0])
-   +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
-      :- Exchange(distribution=[hash[a]])
-      :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
-      :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-      +- Exchange(distribution=[hash[d]])
-         +- Calc(select=[d])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+   +- Exchange(distribution=[keep_input_as_is[hash[a, d]]])
+      +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
+         :- Exchange(distribution=[hash[a]])
+         :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
+         :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+         +- Exchange(distribution=[hash[d]])
+            +- Calc(select=[d])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -278,14 +283,16 @@ LogicalProject(EXPR$0=[$1])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- HashAggregate(isMerge=[false], groupBy=[d], select=[d, SUM(b) AS EXPR$0])
-   +- Calc(select=[d, b])
-      +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
-         :- Exchange(distribution=[hash[a]])
-         :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
-         :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-         +- Exchange(distribution=[hash[d]])
-            +- Calc(select=[d])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+   +- Exchange(distribution=[keep_input_as_is[hash[d]]])
+      +- Calc(select=[d, b])
+         +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+            +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
+               :- Exchange(distribution=[hash[a]])
+               :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
+               :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+               +- Exchange(distribution=[hash[d]])
+                  +- Calc(select=[d])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -550,14 +557,17 @@ LogicalProject(sum_b=[$2], avg_b=[/(CASE(>(COUNT($2) OVER (PARTITION BY $0, $1),
       <![CDATA[
 Calc(select=[sum_b, (CASE((w0$o0 > 0), w0$o1, null:BIGINT) / w0$o0) AS avg_b, w1$o0 AS rn, c])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC, c ASC], window#0=[RANK(*) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, c, sum_b, w0$o0, w0$o1, w1$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- OverAggregate(partitionBy=[a, c], window#0=[COUNT(sum_b) AS w0$o0, $SUM0(sum_b) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[a, c, sum_b, w0$o0, w0$o1])
-            +- Sort(orderBy=[a ASC, c ASC])
-               +- HashAggregate(isMerge=[true], groupBy=[a, c], select=[a, c, Final_SUM(sum$0) AS sum_b])
-                  +- Exchange(distribution=[hash[a, c]])
-                     +- LocalHashAggregate(groupBy=[a, c], select=[a, c, Partial_SUM(b) AS sum$0])
-                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- OverAggregate(partitionBy=[a, c], window#0=[COUNT(sum_b) AS w0$o0, $SUM0(sum_b) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[a, c, sum_b, w0$o0, w0$o1])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[a ASC, c ASC])
+                     +- Exchange(distribution=[keep_input_as_is[hash[a, c]]])
+                        +- HashAggregate(isMerge=[true], groupBy=[a, c], select=[a, c, Final_SUM(sum$0) AS sum_b])
+                           +- Exchange(distribution=[hash[a, c]])
+                              +- LocalHashAggregate(groupBy=[a, c], select=[a, c, Partial_SUM(b) AS sum$0])
+                                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -625,12 +635,14 @@ LogicalProject(sum_b=[$1], avg_b=[/(CASE(>(COUNT($1) OVER (PARTITION BY $0), 0),
       <![CDATA[
 Calc(select=[sum_b, (CASE((w0$o0 > 0), w0$o1, null:BIGINT) / w0$o0) AS avg_b, w1$o0 AS rn, c])
 +- OverAggregate(partitionBy=[c], window#0=[COUNT(sum_b) AS w0$o0, $SUM0(sum_b) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], window#1=[RANK(*) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[c, sum_b, w0$o0, w0$o1, w1$o0])
-   +- Sort(orderBy=[c ASC])
-      +- HashAggregate(isMerge=[true], groupBy=[c], select=[c, Final_SUM(sum$0) AS sum_b])
-         +- Exchange(distribution=[hash[c]])
-            +- LocalHashAggregate(groupBy=[c], select=[c, Partial_SUM(b) AS sum$0])
-               +- Calc(select=[c, b])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC])
+         +- Exchange(distribution=[keep_input_as_is[hash[c]]])
+            +- HashAggregate(isMerge=[true], groupBy=[c], select=[c, Final_SUM(sum$0) AS sum_b])
+               +- Exchange(distribution=[hash[c]])
+                  +- LocalHashAggregate(groupBy=[c], select=[c, Partial_SUM(b) AS sum$0])
+                     +- Calc(select=[c, b])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -658,12 +670,15 @@ LogicalProject(sum_b=[$2], avg_b=[/(CASE(>(COUNT($2) OVER (PARTITION BY $1), 0),
       <![CDATA[
 Calc(select=[sum_b, (CASE((w0$o0 > 0), w0$o1, null:BIGINT) / w0$o0) AS avg_b, w1$o0 AS rn, c])
 +- OverAggregate(partitionBy=[c], window#0=[COUNT(sum_b) AS w0$o0, $SUM0(sum_b) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], window#1=[RANK(*) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[c, sum_b, w0$o0, w0$o1, w1$o0])
-   +- Calc(select=[c, sum_b])
-      +- Sort(orderBy=[c ASC])
-         +- HashAggregate(isMerge=[true], groupBy=[a, c], select=[a, c, Final_SUM(sum$0) AS sum_b])
-            +- Exchange(distribution=[hash[c]])
-               +- LocalHashAggregate(groupBy=[a, c], select=[a, c, Partial_SUM(b) AS sum$0])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Calc(select=[c, sum_b])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[c ASC])
+               +- Exchange(distribution=[forward])
+                  +- HashAggregate(isMerge=[true], groupBy=[a, c], select=[a, c, Final_SUM(sum$0) AS sum_b])
+                     +- Exchange(distribution=[hash[c]])
+                        +- LocalHashAggregate(groupBy=[a, c], select=[a, c, Partial_SUM(b) AS sum$0])
+                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -690,12 +705,14 @@ LogicalProject(a=[$0], b=[$1], rk=[$2])
     <Resource name="optimized exec plan">
       <![CDATA[
 Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[true], select=[a, b, w0$o0])
-+- Sort(orderBy=[a ASC, b ASC])
-   +- HashAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS b])
-      +- Exchange(distribution=[hash[a]])
-         +- LocalHashAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0])
-            +- Calc(select=[a, b])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC, b ASC])
+      +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+         +- HashAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS b])
+            +- Exchange(distribution=[hash[a]])
+               +- LocalHashAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0])
+                  +- Calc(select=[a, b])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -721,13 +738,17 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($1)])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashAggregate(isMerge=[false], groupBy=[a], select=[a, SUM(b) AS EXPR$1])
-+- Calc(select=[a, b])
-   +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a, c], orderBy=[b ASC], global=[true], select=[a, b, c])
-      +- Sort(orderBy=[a ASC, c ASC, b ASC])
-         +- Exchange(distribution=[hash[a]])
-            +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a, c], orderBy=[b ASC], global=[false], select=[a, b, c])
++- Exchange(distribution=[keep_input_as_is[hash[a]]])
+   +- Calc(select=[a, b])
+      +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a, c], orderBy=[b ASC], global=[true], select=[a, b, c])
+            +- Exchange(distribution=[forward])
                +- Sort(orderBy=[a ASC, c ASC, b ASC])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+                  +- Exchange(distribution=[hash[a]])
+                     +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a, c], orderBy=[b ASC], global=[false], select=[a, b, c])
+                        +- Exchange(distribution=[forward])
+                           +- Sort(orderBy=[a ASC, c ASC, b ASC])
+                              +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -753,11 +774,13 @@ LogicalProject(a=[$0], b=[$1], c=[$2], rk=[$3])
     <Resource name="optimized exec plan">
       <![CDATA[
 Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a, c], orderBy=[b ASC], global=[true], select=[a, b, c, w0$o0])
-+- Sort(orderBy=[a ASC, c ASC, b ASC])
-   +- HashAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS b, Final_COUNT(count$1) AS c])
-      +- Exchange(distribution=[hash[a]])
-         +- LocalHashAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC, c ASC, b ASC])
+      +- Exchange(distribution=[keep_input_as_is[hash[a, c]]])
+         +- HashAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS b, Final_COUNT(count$1) AS c])
+            +- Exchange(distribution=[hash[a]])
+               +- LocalHashAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -783,11 +806,13 @@ LogicalProject(a=[$0], b=[$1], c=[$2], rk=[$3])
     <Resource name="optimized exec plan">
       <![CDATA[
 Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a, c], orderBy=[b ASC], global=[true], select=[a, b, c, w0$o0])
-+- Sort(orderBy=[a ASC, c ASC, b ASC])
-   +- HashAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS b, Final_COUNT(count$1) AS c])
-      +- Exchange(distribution=[hash[a]])
-         +- LocalHashAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC, c ASC, b ASC])
+      +- Exchange(distribution=[keep_input_as_is[hash[a, c]]])
+         +- HashAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS b, Final_COUNT(count$1) AS c])
+            +- Exchange(distribution=[hash[a]])
+               +- LocalHashAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -837,12 +862,14 @@ LogicalProject(a=[$0], b=[$1], rk=[$2])
     <Resource name="optimized exec plan">
       <![CDATA[
 Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[], orderBy=[b ASC], global=[true], select=[a, b, w0$o0])
-+- Sort(orderBy=[b ASC])
-   +- HashAggregate(isMerge=[true], select=[Final_COUNT(count$0) AS a, Final_SUM(sum$1) AS b])
-      +- Exchange(distribution=[single])
-         +- LocalHashAggregate(select=[Partial_COUNT(a) AS count$0, Partial_SUM(b) AS sum$1])
-            +- Calc(select=[a, b])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[b ASC])
+      +- Exchange(distribution=[forward])
+         +- HashAggregate(isMerge=[true], select=[Final_COUNT(count$0) AS a, Final_SUM(sum$1) AS b])
+            +- Exchange(distribution=[single])
+               +- LocalHashAggregate(select=[Partial_COUNT(a) AS count$0, Partial_SUM(b) AS sum$1])
+                  +- Calc(select=[a, b])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -869,12 +896,14 @@ LogicalProject(a=[$0], b=[$1], rk=[$2])
     <Resource name="optimized exec plan">
       <![CDATA[
 Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=10], partitionBy=[a], orderBy=[b ASC], global=[true], select=[a, b, w0$o0])
-+- Sort(orderBy=[a ASC, b ASC])
-   +- HashAggregate(isMerge=[true], select=[Final_COUNT(count$0) AS a, Final_SUM(sum$1) AS b])
-      +- Exchange(distribution=[single])
-         +- LocalHashAggregate(select=[Partial_COUNT(a) AS count$0, Partial_SUM(b) AS sum$1])
-            +- Calc(select=[a, b])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC, b ASC])
+      +- Exchange(distribution=[keep_input_as_is[hash[a]]])
+         +- HashAggregate(isMerge=[true], select=[Final_COUNT(count$0) AS a, Final_SUM(sum$1) AS b])
+            +- Exchange(distribution=[single])
+               +- LocalHashAggregate(select=[Partial_COUNT(a) AS count$0, Partial_SUM(b) AS sum$1])
+                  +- Calc(select=[a, b])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -900,15 +929,18 @@ LogicalProject(EXPR$0=[$1])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortAggregate(isMerge=[false], groupBy=[a], select=[a, SUM(b) AS EXPR$0])
-   +- Calc(select=[a, b])
-      +- Sort(orderBy=[a ASC])
-         +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
-            :- Exchange(distribution=[hash[a]])
-            :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
-            :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-            +- Exchange(distribution=[hash[d]])
-               +- Calc(select=[d])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+   +- Exchange(distribution=[forward])
+      +- Calc(select=[a, b])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[a ASC])
+               +- Exchange(distribution=[forward])
+                  +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
+                     :- Exchange(distribution=[hash[a]])
+                     :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
+                     :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+                     +- Exchange(distribution=[hash[d]])
+                        +- Calc(select=[d])
+                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -934,14 +966,16 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortAggregate(isMerge=[false], groupBy=[a, d], select=[a, d, SUM(b) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, d ASC])
-      +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
-         :- Exchange(distribution=[hash[a]])
-         :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
-         :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-         +- Exchange(distribution=[hash[d]])
-            +- Calc(select=[d])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, d ASC])
+         +- Exchange(distribution=[keep_input_as_is[hash[a, d]]])
+            +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
+               :- Exchange(distribution=[hash[a]])
+               :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
+               :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+               +- Exchange(distribution=[hash[d]])
+                  +- Calc(select=[d])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -967,15 +1001,18 @@ LogicalProject(EXPR$0=[$1])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortAggregate(isMerge=[false], groupBy=[d], select=[d, SUM(b) AS EXPR$0])
-   +- Calc(select=[d, b])
-      +- Sort(orderBy=[d ASC])
-         +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
-            :- Exchange(distribution=[hash[a]])
-            :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
-            :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-            +- Exchange(distribution=[hash[d]])
-               +- Calc(select=[d])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+   +- Exchange(distribution=[forward])
+      +- Calc(select=[d, b])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[d ASC])
+               +- Exchange(distribution=[forward])
+                  +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d], build=[left])
+                     :- Exchange(distribution=[hash[a]])
+                     :  +- Calc(select=[a, b], where=[LIKE(c, 'He%')])
+                     :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+                     +- Exchange(distribution=[hash[d]])
+                        +- Calc(select=[d])
+                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/SetOperatorsTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/SetOperatorsTest.xml
index 7b89148eab2..717adb1ad89 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/SetOperatorsTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/SetOperatorsTest.xml
@@ -32,13 +32,14 @@ LogicalIntersect(all=[false])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashAggregate(isMerge=[false], groupBy=[c], select=[c])
-+- HashJoin(joinType=[LeftSemiJoin], where=[IS NOT DISTINCT FROM(c, f)], select=[c], build=[left])
-   :- Exchange(distribution=[hash[c]])
-   :  +- Calc(select=[c])
-   :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-   +- Exchange(distribution=[hash[f]])
-      +- Calc(select=[f])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
++- Exchange(distribution=[keep_input_as_is[hash[c]]])
+   +- HashJoin(joinType=[LeftSemiJoin], where=[IS NOT DISTINCT FROM(c, f)], select=[c], build=[left])
+      :- Exchange(distribution=[hash[c]])
+      :  +- Calc(select=[c])
+      :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+      +- Exchange(distribution=[hash[f]])
+         +- Calc(select=[f])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -129,13 +130,14 @@ LogicalProject(a=[$0])
       <![CDATA[
 Calc(select=[a])
 +- HashAggregate(isMerge=[false], groupBy=[a, b], select=[a, b])
-   +- HashJoin(joinType=[LeftSemiJoin], where=[(((a = d) OR (a IS NULL AND d IS NULL)) AND ((b = e) OR (b IS NULL AND e IS NULL)))], select=[a, b], build=[left])
-      :- Exchange(distribution=[hash[a, b]])
-      :  +- Calc(select=[a, b])
-      :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-      +- Exchange(distribution=[hash[d, e]])
-         +- Calc(select=[d, e])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+   +- Exchange(distribution=[keep_input_as_is[hash[a, b]]])
+      +- HashJoin(joinType=[LeftSemiJoin], where=[(((a = d) OR (a IS NULL AND d IS NULL)) AND ((b = e) OR (b IS NULL AND e IS NULL)))], select=[a, b], build=[left])
+         :- Exchange(distribution=[hash[a, b]])
+         :  +- Calc(select=[a, b])
+         :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+         +- Exchange(distribution=[hash[d, e]])
+            +- Calc(select=[d, e])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -155,13 +157,14 @@ LogicalMinus(all=[false])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashAggregate(isMerge=[false], groupBy=[c], select=[c])
-+- HashJoin(joinType=[LeftAntiJoin], where=[IS NOT DISTINCT FROM(c, f)], select=[c], build=[left])
-   :- Exchange(distribution=[hash[c]])
-   :  +- Calc(select=[c])
-   :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-   +- Exchange(distribution=[hash[f]])
-      +- Calc(select=[f])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
++- Exchange(distribution=[keep_input_as_is[hash[c]]])
+   +- HashJoin(joinType=[LeftAntiJoin], where=[IS NOT DISTINCT FROM(c, f)], select=[c], build=[left])
+      :- Exchange(distribution=[hash[c]])
+      :  +- Calc(select=[c])
+      :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+      +- Exchange(distribution=[hash[f]])
+         +- Calc(select=[f])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -254,11 +257,12 @@ LogicalMinus(all=[false])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashAggregate(isMerge=[false], groupBy=[a, b, c], select=[a, b, c])
-+- HashJoin(joinType=[LeftAntiJoin], where=[(((a = a0) OR (a IS NULL AND a0 IS NULL)) AND ((b = b0) OR (b IS NULL AND b0 IS NULL)) AND ((c = c0) OR (c IS NULL AND c0 IS NULL)))], select=[a, b, c], build=[left])
-   :- Exchange(distribution=[hash[a, b, c]])
-   :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])(reuse_id=[1])
-   +- Exchange(distribution=[hash[a, b, c]], shuffle_mode=[BATCH])
-      +- Reused(reference_id=[1])
++- Exchange(distribution=[keep_input_as_is[hash[a, b, c]]])
+   +- HashJoin(joinType=[LeftAntiJoin], where=[(((a = a0) OR (a IS NULL AND a0 IS NULL)) AND ((b = b0) OR (b IS NULL AND b0 IS NULL)) AND ((c = c0) OR (c IS NULL AND c0 IS NULL)))], select=[a, b, c], build=[left])
+      :- Exchange(distribution=[hash[a, b, c]])
+      :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])(reuse_id=[1])
+      +- Exchange(distribution=[hash[a, b, c]], shuffle_mode=[BATCH])
+         +- Reused(reference_id=[1])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/SubplanReuseTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/SubplanReuseTest.xml
index aa4cd5a629e..6636e19c0fe 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/SubplanReuseTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/SubplanReuseTest.xml
@@ -208,7 +208,7 @@ LogicalProject(a=[$0], b=[$1], d=[$2], e=[$3], a0=[$4], b0=[$5], d0=[$6], e0=[$7
     <Resource name="optimized exec plan">
       <![CDATA[
 HashJoin(joinType=[InnerJoin], where=[(b = e0)], select=[a, b, d, e, a0, b0, d0, e0], build=[right])
-:- Exchange(distribution=[hash[b]], shuffle_mode=[BATCH])
+:- Exchange(distribution=[hash[b]])
 :  +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d, e], build=[right])
 :     :- Exchange(distribution=[hash[a]])
 :     :  +- Calc(select=[a, b], where=[(a < 10)])
@@ -257,7 +257,7 @@ LogicalProject(a=[$0], b=[$1], d=[$2], e=[$3], a0=[$4], b0=[$5], d0=[$6], e0=[$7
     <Resource name="optimized exec plan">
       <![CDATA[
 HashJoin(joinType=[InnerJoin], where=[(b = e0)], select=[a, b, d, e, a0, b0, d0, e0], build=[right])
-:- Exchange(distribution=[hash[b]], shuffle_mode=[BATCH])
+:- Exchange(distribution=[hash[b]])
 :  +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, d, e], build=[right])
 :     :- Exchange(distribution=[hash[a]])
 :     :  +- Calc(select=[a, b], where=[(a < 10)])
@@ -341,26 +341,28 @@ LogicalProject(c=[$0], e=[$1], avg_b=[$2], sum_b=[$3], psum=[$4], nsum=[$5], avg
     <Resource name="optimized exec plan">
       <![CDATA[
 Calc(select=[c, e, avg_b, sum_b, sum_b0 AS psum, sum_b1 AS nsum, avg_b0 AS avg_b2])
-+- MultipleInput(readOrder=[2,0,1], members=[\nHashJoin(joinType=[InnerJoin], where=[((c = c0) AND (e = e0) AND (rn = $f5))], select=[sum_b, avg_b, rn, c, e, sum_b0, avg_b0, sum_b1, c0, e0, $f5], build=[left])\n:- Calc(select=[sum_b, avg_b, rn, c, e, sum_b0, avg_b0])\n:  +- HashJoin(joinType=[InnerJoin], where=[((c = c0) AND (e = e0) AND (rn = $f5))], select=[sum_b, avg_b, rn, c, e, sum_b0, avg_b0, c0, e0, $f5], build=[left])\n:     :- [#2] Exchange(distribution=[hash[c, e, rn]])\n:      [...]
-   :- Exchange(distribution=[hash[c, e, $f5]], shuffle_mode=[BATCH])
++- MultipleInput(readOrder=[2,0,1], members=[\nHashJoin(joinType=[InnerJoin], where=[((c = c0) AND (e = e0) AND (rn = $f5))], select=[sum_b, avg_b, rn, c, e, sum_b0, avg_b0, sum_b1, c0, e0, $f5], build=[left])\n:- Calc(select=[sum_b, avg_b, rn, c, e, sum_b0, avg_b0])\n:  +- HashJoin(joinType=[InnerJoin], where=[((c = c0) AND (e = e0) AND (rn = $f5))], select=[sum_b, avg_b, rn, c, e, sum_b0, avg_b0, c0, e0, $f5], build=[left])\n:     :- [#2] Exchange(distribution=[hash[c, e, rn]])\n:      [...]
+   :- Exchange(distribution=[hash[c, e, $f5]])
    :  +- Calc(select=[sum_b, c, e, (w1$o0 - 1) AS $f5], where=[(c <> '')])
    :     +- OverAggregate(partitionBy=[c, e], window#0=[COUNT(sum_b) AS w0$o0, $SUM0(sum_b) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], window#1=[RANK(*) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[c, e, sum_b, w0$o0, w0$o1, w1$o0])(reuse_id=[1])
-   :        +- Sort(orderBy=[c ASC, e ASC])
-   :           +- HashAggregate(isMerge=[true], groupBy=[c, e], select=[c, e, Final_SUM(sum$0) AS sum_b])
-   :              +- Exchange(distribution=[hash[c, e]])
-   :                 +- LocalHashAggregate(groupBy=[c, e], select=[c, e, Partial_SUM(b) AS sum$0])
-   :                    +- Calc(select=[c, e, b])
-   :                       +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, c, d, e], build=[right])
-   :                          :- Exchange(distribution=[hash[a]])
-   :                          :  +- Calc(select=[a, b, c], where=[c IS NOT NULL])
-   :                          :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-   :                          +- Exchange(distribution=[hash[d]])
-   :                             +- Calc(select=[d, e], where=[(e > 10)])
-   :                                +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+   :        +- Exchange(distribution=[forward])
+   :           +- Sort(orderBy=[c ASC, e ASC])
+   :              +- Exchange(distribution=[keep_input_as_is[hash[c, e]]])
+   :                 +- HashAggregate(isMerge=[true], groupBy=[c, e], select=[c, e, Final_SUM(sum$0) AS sum_b])
+   :                    +- Exchange(distribution=[hash[c, e]])
+   :                       +- LocalHashAggregate(groupBy=[c, e], select=[c, e, Partial_SUM(b) AS sum$0])
+   :                          +- Calc(select=[c, e, b])
+   :                             +- HashJoin(joinType=[InnerJoin], where=[(a = d)], select=[a, b, c, d, e], build=[right])
+   :                                :- Exchange(distribution=[hash[a]])
+   :                                :  +- Calc(select=[a, b, c], where=[c IS NOT NULL])
+   :                                :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   :                                +- Exchange(distribution=[hash[d]])
+   :                                   +- Calc(select=[d, e], where=[(e > 10)])
+   :                                      +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
    :- Exchange(distribution=[hash[c, e, rn]])
    :  +- Calc(select=[sum_b, (CASE((w0$o0 > 0), w0$o1, null:BIGINT) / w0$o0) AS avg_b, w1$o0 AS rn, c, e], where=[((c <> '') AND ((sum_b - (CASE((w0$o0 > 0), w0$o1, null:BIGINT) / w0$o0)) > 3))])
    :     +- Reused(reference_id=[1])
-   +- Exchange(distribution=[hash[c, e, $f5]], shuffle_mode=[BATCH])
+   +- Exchange(distribution=[hash[c, e, $f5]])
       +- Calc(select=[sum_b, (CASE((w0$o0 > 0), w0$o1, null:BIGINT) / w0$o0) AS avg_b, c, e, (w1$o0 + 1) AS $f5], where=[(c <> '')])
          +- Reused(reference_id=[1])
 ]]>
@@ -390,12 +392,13 @@ LogicalProject(c=[$0], a=[$1], b=[$2], c0=[$3], a0=[$4], b0=[$5])
       <![CDATA[
 Calc(select=[c, a, b, c0, a1, b0])
 +- HashJoin(joinType=[InnerJoin], where=[(a0 = b0)], select=[c, a, b, a0, c0, a1, b0], build=[right])
-   :- Exchange(distribution=[hash[a0]], shuffle_mode=[BATCH])
+   :- Exchange(distribution=[hash[a0]])
    :  +- Calc(select=[c, a, b, CAST(a AS BIGINT) AS a0])
    :     +- SortAggregate(isMerge=[false], groupBy=[c], select=[c, MyFirst(a) AS a, MyLast(b) AS b])(reuse_id=[1])
-   :        +- Sort(orderBy=[c ASC])
-   :           +- Exchange(distribution=[hash[c]])
-   :              +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   :        +- Exchange(distribution=[forward])
+   :           +- Sort(orderBy=[c ASC])
+   :              +- Exchange(distribution=[hash[c]])
+   :                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
    +- Exchange(distribution=[hash[b]])
       +- Calc(select=[c, a, b], where=[(a > 1)])
          +- Reused(reference_id=[1])
@@ -698,7 +701,7 @@ LogicalProject(c=[$0], a=[$1], b=[$2], c0=[$3], a0=[$4], b0=[$5])
       <![CDATA[
 Calc(select=[c, a, b, c0, a1, b0])
 +- HashJoin(joinType=[InnerJoin], where=[(a0 = b0)], select=[c, a, b, a0, c0, a1, b0], build=[right])
-   :- Exchange(distribution=[hash[a0]], shuffle_mode=[BATCH])
+   :- Exchange(distribution=[hash[a0]])
    :  +- Calc(select=[c, a, b, CAST(a AS BIGINT) AS a0])
    :     +- HashAggregate(isMerge=[true], groupBy=[c], select=[c, Final_SUM(sum$0) AS a, Final_SUM(sum$1) AS b])(reuse_id=[1])
    :        +- Exchange(distribution=[hash[c]])
@@ -744,7 +747,8 @@ HashJoin(joinType=[InnerJoin], where=[(a = d0)], select=[a, b, c, d, e, f, a0, b
 :     :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 :     +- Exchange(distribution=[hash[d]])
 :        +- LegacyTableSourceScan(table=[[default_catalog, default_database, y, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
-+- Reused(reference_id=[1])
++- Exchange(distribution=[keep_input_as_is[hash[d]]])
+   +- Reused(reference_id=[1])
 ]]>
     </Resource>
   </TestCase>
@@ -777,7 +781,7 @@ LogicalProject(a=[$0], b=[$1], c=[$2], d=[$3], e=[$4], f=[$5], a0=[$6], b0=[$7],
       <![CDATA[
 Calc(select=[a, b, c, d, e, f, a1, b0, c0, d0, e0, f0])
 +- HashJoin(joinType=[InnerJoin], where=[(a0 = b0)], select=[a, b, c, d, e, f, a0, a1, b0, c0, d0, e0, f0], build=[right])
-   :- Exchange(distribution=[hash[a0]], shuffle_mode=[BATCH])
+   :- Exchange(distribution=[hash[a0]])
    :  +- Calc(select=[a, b, c, d, e, f, CAST(a AS BIGINT) AS a0])
    :     +- NestedLoopJoin(joinType=[InnerJoin], where=[((ABS(a) = ABS(d)) OR (c = f))], select=[a, b, c, d, e, f], build=[left])(reuse_id=[1])
    :        :- Exchange(distribution=[broadcast])
@@ -819,7 +823,7 @@ LogicalProject(a=[$0], b=[$1], c=[$2], d=[$3], e=[$4], f=[$5], a0=[$6], b0=[$7],
       <![CDATA[
 Calc(select=[a, b, c, d, e, f, a1, b0, c0, d0, e0, f0])
 +- HashJoin(joinType=[InnerJoin], where=[(a0 = b0)], select=[a, b, c, d, e, f, a0, a1, b0, c0, d0, e0, f0], build=[right])
-   :- Exchange(distribution=[hash[a0]], shuffle_mode=[BATCH])
+   :- Exchange(distribution=[hash[a0]])
    :  +- Calc(select=[a, b, c, d, e, f, CAST(a AS BIGINT) AS a0])
    :     +- NestedLoopJoin(joinType=[InnerJoin], where=[((random_udf(a) = random_udf(d)) OR (c = f))], select=[a, b, c, d, e, f], build=[left])(reuse_id=[1])
    :        :- Exchange(distribution=[broadcast])
@@ -927,12 +931,13 @@ LogicalProject(a=[$0], b=[$1], EXPR$2=[$2], a0=[$3], b0=[$4], EXPR$20=[$5])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashJoin(joinType=[InnerJoin], where=[(a = a0)], select=[a, b, w0$o0, a0, b0, w0$o00], build=[right])
-:- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
+:- Exchange(distribution=[hash[a]])
 :  +- Calc(select=[a, b, w0$o0], where=[(b < 100)])
 :     +- OverAggregate(partitionBy=[c], orderBy=[c DESC], window#0=[MyFirst(c) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0])(reuse_id=[1])
-:        +- Sort(orderBy=[c DESC])
-:           +- Exchange(distribution=[hash[c]])
-:              +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+:        +- Exchange(distribution=[forward])
+:           +- Sort(orderBy=[c DESC])
+:              +- Exchange(distribution=[hash[c]])
+:                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 +- Exchange(distribution=[hash[a]])
    +- Calc(select=[a, b, w0$o0], where=[(b > 10)])
       +- Reused(reference_id=[1])
@@ -962,7 +967,7 @@ LogicalProject(c=[$0], a=[$1], b=[$2], c0=[$3], a0=[$4], b0=[$5])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashJoin(joinType=[InnerJoin], where=[(a = a0)], select=[c, a, b, c0, a0, b0], build=[right])
-:- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
+:- Exchange(distribution=[hash[a]])
 :  +- Calc(select=[c, a, b], where=[(a > 1)])
 :     +- HashAggregate(isMerge=[true], groupBy=[c], select=[c, Final_SUM(sum$0) AS a, Final_SUM(sum$1) AS b])(reuse_id=[1])
 :        +- Exchange(distribution=[hash[c]])
@@ -998,14 +1003,16 @@ LogicalProject(c=[$0], a=[$1], b=[$2], c0=[$3], a0=[$4], b0=[$5])
       <![CDATA[
 Calc(select=[c, a, b, c0, a1, b0])
 +- HashJoin(joinType=[InnerJoin], where=[(a0 = b0)], select=[c, a, b, a0, c0, a1, b0], build=[right])
-   :- Exchange(distribution=[hash[a0]], shuffle_mode=[BATCH])
+   :- Exchange(distribution=[hash[a0]])
    :  +- Calc(select=[c, a, b, CAST(a AS BIGINT) AS a0])
    :     +- SortAggregate(isMerge=[true], groupBy=[c], select=[c, Final_SUM(sum$0) AS a, Final_SUM(sum$1) AS b])(reuse_id=[1])
-   :        +- Sort(orderBy=[c ASC])
-   :           +- Exchange(distribution=[hash[c]])
-   :              +- LocalSortAggregate(groupBy=[c], select=[c, Partial_SUM(a) AS sum$0, Partial_SUM(b) AS sum$1])
-   :                 +- Sort(orderBy=[c ASC])
-   :                    +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   :        +- Exchange(distribution=[forward])
+   :           +- Sort(orderBy=[c ASC])
+   :              +- Exchange(distribution=[hash[c]])
+   :                 +- LocalSortAggregate(groupBy=[c], select=[c, Partial_SUM(a) AS sum$0, Partial_SUM(b) AS sum$1])
+   :                    +- Exchange(distribution=[forward])
+   :                       +- Sort(orderBy=[c ASC])
+   :                          +- LegacyTableSourceScan(table=[[default_catalog, default_database, x, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
    +- Exchange(distribution=[hash[b]])
       +- Calc(select=[c, a, b], where=[(a > 1)])
          +- Reused(reference_id=[1])
@@ -1033,7 +1040,7 @@ LogicalProject(a=[$0], b=[$1], EXPR$2=[$2], a0=[$3], b0=[$4], EXPR$20=[$5])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashJoin(joinType=[InnerJoin], where=[(a = a0)], select=[a, b, w0$o0, a0, b0, w0$o00], build=[right])
-:- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
+:- Exchange(distribution=[hash[a]])
 :  +- Calc(select=[a, b, w0$o0], where=[(b < 100)])
 :     +- OverAggregate(orderBy=[c DESC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0])(reuse_id=[1])
 :        +- Sort(orderBy=[c DESC])
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/UnnestTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/UnnestTest.xml
index ef3bc2e29d0..267749ba5c3 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/UnnestTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/UnnestTest.xml
@@ -69,12 +69,14 @@ LogicalProject(b=[$0], s=[$2])
 Calc(select=[b, f0 AS s])
 +- Correlate(invocation=[$UNNEST_ROWS$1($cor0.set)], correlate=[table($UNNEST_ROWS$1($cor0.set))], select=[b,set,f0], rowType=[RecordType(BIGINT b, BIGINT MULTISET set, BIGINT f0)], joinType=[INNER])
    +- SortWindowAggregate(groupBy=[b], window=[TumblingGroupWindow('w$, rowtime, 3000)], select=[b, Final_COLLECT(set) AS set])
-      +- Sort(orderBy=[b ASC, assignedWindow$ ASC])
-         +- Exchange(distribution=[hash[b]])
-            +- LocalSortWindowAggregate(groupBy=[b], window=[TumblingGroupWindow('w$, rowtime, 3000)], select=[b, Partial_COLLECT(b) AS set])
-               +- Sort(orderBy=[b ASC, rowtime ASC])
-                  +- Calc(select=[b, rowtime], where=[(b < 3)])
-                     +- BoundedStreamScan(table=[[default_catalog, default_database, MyTable]], fields=[a, b, c, rowtime])
+      +- Exchange(distribution=[forward])
+         +- Sort(orderBy=[b ASC, assignedWindow$ ASC])
+            +- Exchange(distribution=[hash[b]])
+               +- LocalSortWindowAggregate(groupBy=[b], window=[TumblingGroupWindow('w$, rowtime, 3000)], select=[b, Partial_COLLECT(b) AS set])
+                  +- Exchange(distribution=[forward])
+                     +- Sort(orderBy=[b ASC, rowtime ASC])
+                        +- Calc(select=[b, rowtime], where=[(b < 3)])
+                           +- BoundedStreamScan(table=[[default_catalog, default_database, MyTable]], fields=[a, b, c, rowtime])
 ]]>
     </Resource>
   </TestCase>
@@ -159,12 +161,14 @@ LogicalProject(a=[$0], s=[$2])
 Calc(select=[a, f0 AS s])
 +- Correlate(invocation=[$UNNEST_ROWS$1($cor0.set)], correlate=[table($UNNEST_ROWS$1($cor0.set))], select=[a,set,f0], rowType=[RecordType(INTEGER a, VARCHAR(2147483647) MULTISET set, VARCHAR(2147483647) f0)], joinType=[LEFT])
    +- SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_COLLECT(set) AS set])
-      +- Sort(orderBy=[a ASC])
-         +- Exchange(distribution=[hash[a]])
-            +- LocalSortAggregate(groupBy=[a], select=[a, Partial_COLLECT(b) AS set])
-               +- Sort(orderBy=[a ASC])
-                  +- Calc(select=[a, b], where=[(a < 5)])
-                     +- BoundedStreamScan(table=[[default_catalog, default_database, MyTable]], fields=[a, b, c])
+      +- Exchange(distribution=[forward])
+         +- Sort(orderBy=[a ASC])
+            +- Exchange(distribution=[hash[a]])
+               +- LocalSortAggregate(groupBy=[a], select=[a, Partial_COLLECT(b) AS set])
+                  +- Exchange(distribution=[forward])
+                     +- Sort(orderBy=[a ASC])
+                        +- Calc(select=[a, b], where=[(a < 5)])
+                           +- BoundedStreamScan(table=[[default_catalog, default_database, MyTable]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -217,12 +221,14 @@ LogicalProject(b=[$0], id=[$2], point=[$3])
 Calc(select=[b, _1 AS id, _2 AS point])
 +- Correlate(invocation=[$UNNEST_ROWS$1($cor0.set)], correlate=[table($UNNEST_ROWS$1($cor0.set))], select=[b,set,_1,_2], rowType=[RecordType(INTEGER b, RecordType:peek_no_expand(INTEGER _1, VARCHAR(2147483647) _2) MULTISET set, INTEGER _1, VARCHAR(2147483647) _2)], joinType=[INNER])
    +- SortAggregate(isMerge=[true], groupBy=[b], select=[b, Final_COLLECT(set) AS set])
-      +- Sort(orderBy=[b ASC])
-         +- Exchange(distribution=[hash[b]])
-            +- LocalSortAggregate(groupBy=[b], select=[b, Partial_COLLECT(c) AS set])
-               +- Sort(orderBy=[b ASC])
-                  +- Calc(select=[b, c], where=[(b < 3)])
-                     +- BoundedStreamScan(table=[[default_catalog, default_database, MyTable]], fields=[a, b, c])
+      +- Exchange(distribution=[forward])
+         +- Sort(orderBy=[b ASC])
+            +- Exchange(distribution=[hash[b]])
+               +- LocalSortAggregate(groupBy=[b], select=[b, Partial_COLLECT(c) AS set])
+                  +- Exchange(distribution=[forward])
+                     +- Sort(orderBy=[b ASC])
+                        +- Calc(select=[b, c], where=[(b < 3)])
+                           +- BoundedStreamScan(table=[[default_catalog, default_database, MyTable]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/WindowTableFunctionTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/WindowTableFunctionTest.xml
index e98957cf7e9..a0b54ffde7d 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/WindowTableFunctionTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/WindowTableFunctionTest.xml
@@ -146,14 +146,16 @@ LogicalProject(EXPR$0=[$3])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortAggregate(isMerge=[true], groupBy=[window_start, window_end, a], select=[window_start, window_end, a, Final_MAX(max$0) AS EXPR$0])
-   +- Sort(orderBy=[window_start ASC, window_end ASC, a ASC])
-      +- Exchange(distribution=[hash[window_start, window_end, a]])
-         +- LocalSortAggregate(groupBy=[window_start, window_end, a], select=[window_start, window_end, a, Partial_MAX(c) AS max$0])
-            +- Sort(orderBy=[window_start ASC, window_end ASC, a ASC])
-               +- Calc(select=[window_start, window_end, a, c])
-                  +- WindowTableFunction(window=[TUMBLE(time_col=[ts], size=[3 s])])
-                     +- Calc(select=[a, c, ts])
-                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c, d, ts)]]], fields=[a, b, c, d, ts])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[window_start ASC, window_end ASC, a ASC])
+         +- Exchange(distribution=[hash[window_start, window_end, a]])
+            +- LocalSortAggregate(groupBy=[window_start, window_end, a], select=[window_start, window_end, a, Partial_MAX(c) AS max$0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[window_start ASC, window_end ASC, a ASC])
+                     +- Calc(select=[window_start, window_end, a, c])
+                        +- WindowTableFunction(window=[TUMBLE(time_col=[ts], size=[3 s])])
+                           +- Calc(select=[a, c, ts])
+                              +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c, d, ts)]]], fields=[a, b, c, d, ts])
 ]]>
     </Resource>
   </TestCase>
@@ -181,14 +183,16 @@ LogicalAggregate(group=[{0, 1, 2}], EXPR$3=[MAX($3)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[true], groupBy=[window_start, window_end, a], select=[window_start, window_end, a, Final_MAX(max$0) AS EXPR$3])
-+- Sort(orderBy=[window_start ASC, window_end ASC, a ASC])
-   +- Exchange(distribution=[hash[window_start, window_end, a]])
-      +- LocalSortAggregate(groupBy=[window_start, window_end, a], select=[window_start, window_end, a, Partial_MAX(c) AS max$0])
-         +- Sort(orderBy=[window_start ASC, window_end ASC, a ASC])
-            +- Calc(select=[window_start, window_end, a, c])
-               +- WindowTableFunction(window=[TUMBLE(time_col=[ts], size=[3 s])])
-                  +- Calc(select=[a, c, ts])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c, d, ts)]]], fields=[a, b, c, d, ts])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[window_start ASC, window_end ASC, a ASC])
+      +- Exchange(distribution=[hash[window_start, window_end, a]])
+         +- LocalSortAggregate(groupBy=[window_start, window_end, a], select=[window_start, window_end, a, Partial_MAX(c) AS max$0])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[window_start ASC, window_end ASC, a ASC])
+                  +- Calc(select=[window_start, window_end, a, c])
+                     +- WindowTableFunction(window=[TUMBLE(time_col=[ts], size=[3 s])])
+                        +- Calc(select=[a, c, ts])
+                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c, d, ts)]]], fields=[a, b, c, d, ts])
 ]]>
     </Resource>
   </TestCase>
@@ -258,12 +262,14 @@ LogicalProject(ts=[$0], a=[$1], b=[$2], c=[$3], window_start=[$4], window_end=[$
     <Resource name="optimized exec plan">
       <![CDATA[
 Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=3], partitionBy=[a, window_start, window_end], orderBy=[b ASC], global=[true], select=[ts, a, b, c, window_start, window_end, window_time, w0$o0])
-+- Sort(orderBy=[a ASC, window_start ASC, window_end ASC, b ASC])
-   +- Exchange(distribution=[hash[a, window_start, window_end]])
-      +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=3], partitionBy=[a, window_start, window_end], orderBy=[b ASC], global=[false], select=[ts, a, b, c, window_start, window_end, window_time])
-         +- Sort(orderBy=[a ASC, window_start ASC, window_end ASC, b ASC])
-            +- WindowTableFunction(window=[TUMBLE(time_col=[ts], size=[15 min])])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC, window_start ASC, window_end ASC, b ASC])
+      +- Exchange(distribution=[hash[a, window_start, window_end]])
+         +- Rank(rankType=[RANK], rankRange=[rankStart=1, rankEnd=3], partitionBy=[a, window_start, window_end], orderBy=[b ASC], global=[false], select=[ts, a, b, c, window_start, window_end, window_time])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC, window_start ASC, window_end ASC, b ASC])
+                  +- WindowTableFunction(window=[TUMBLE(time_col=[ts], size=[15 min])])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/AggregateReduceGroupingTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/AggregateReduceGroupingTest.xml
index 72ddf48e4b6..ca504fdc51e 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/AggregateReduceGroupingTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/AggregateReduceGroupingTest.xml
@@ -90,13 +90,14 @@ LogicalAggregate(group=[{0, 1, 2, 3}], EXPR$4=[COUNT($4)])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashAggregate(isMerge=[false], groupBy=[a1], auxGrouping=[b1, a2, b2], select=[a1, b1, a2, b2, COUNT(c1) AS EXPR$4])
-+- HashJoin(joinType=[InnerJoin], where=[(a1 = b2)], select=[a1, b1, c1, a2, b2], build=[right])
-   :- Exchange(distribution=[hash[a1]])
-   :  +- Calc(select=[a1, b1, c1])
-   :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
-   +- Exchange(distribution=[hash[b2]])
-      +- Calc(select=[a2, b2])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(a2, b2, c2)]]], fields=[a2, b2, c2])
++- Exchange(distribution=[keep_input_as_is[hash[a1]]])
+   +- HashJoin(joinType=[InnerJoin], where=[(a1 = b2)], select=[a1, b1, c1, a2, b2], build=[right])
+      :- Exchange(distribution=[hash[a1]])
+      :  +- Calc(select=[a1, b1, c1])
+      :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
+      +- Exchange(distribution=[hash[b2]])
+         +- Calc(select=[a2, b2])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(a2, b2, c2)]]], fields=[a2, b2, c2])
 ]]>
     </Resource>
   </TestCase>
@@ -179,13 +180,14 @@ LogicalAggregate(group=[{0, 1, 2, 3}], EXPR$4=[COUNT($4)])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashAggregate(isMerge=[false], groupBy=[a1], auxGrouping=[b1, a2, b2], select=[a1, b1, a2, b2, COUNT(c1) AS EXPR$4])
-+- HashJoin(joinType=[LeftOuterJoin], where=[(a1 = b2)], select=[a1, b1, c1, a2, b2], build=[right])
-   :- Exchange(distribution=[hash[a1]])
-   :  +- Calc(select=[a1, b1, c1])
-   :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
-   +- Exchange(distribution=[hash[b2]])
-      +- Calc(select=[a2, b2])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(a2, b2, c2)]]], fields=[a2, b2, c2])
++- Exchange(distribution=[keep_input_as_is[hash[a1]]])
+   +- HashJoin(joinType=[LeftOuterJoin], where=[(a1 = b2)], select=[a1, b1, c1, a2, b2], build=[right])
+      :- Exchange(distribution=[hash[a1]])
+      :  +- Calc(select=[a1, b1, c1])
+      :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
+      +- Exchange(distribution=[hash[b2]])
+         +- Calc(select=[a2, b2])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(a2, b2, c2)]]], fields=[a2, b2, c2])
 ]]>
     </Resource>
   </TestCase>
@@ -233,13 +235,14 @@ LogicalAggregate(group=[{0, 1, 2, 3}], EXPR$4=[COUNT($4)])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashAggregate(isMerge=[false], groupBy=[a3, b3], auxGrouping=[a1, b1], select=[a3, b3, a1, b1, COUNT(c1) AS EXPR$4])
-+- HashJoin(joinType=[LeftOuterJoin], where=[(a1 = a3)], select=[a3, b3, a1, b1, c1], build=[left])
-   :- Exchange(distribution=[hash[a3]])
-   :  +- Calc(select=[a3, b3])
-   :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T3, source: [TestTableSource(a3, b3, c3, d3)]]], fields=[a3, b3, c3, d3])
-   +- Exchange(distribution=[hash[a1]])
-      +- Calc(select=[a1, b1, c1])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
++- Exchange(distribution=[keep_input_as_is[hash[a3, b3]]])
+   +- HashJoin(joinType=[LeftOuterJoin], where=[(a1 = a3)], select=[a3, b3, a1, b1, c1], build=[left])
+      :- Exchange(distribution=[hash[a3]])
+      :  +- Calc(select=[a3, b3])
+      :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T3, source: [TestTableSource(a3, b3, c3, d3)]]], fields=[a3, b3, c3, d3])
+      +- Exchange(distribution=[hash[a1]])
+         +- Calc(select=[a1, b1, c1])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
 ]]>
     </Resource>
   </TestCase>
@@ -262,9 +265,10 @@ Calc(select=[a1, b1, c, EXPR$3])
       +- LocalHashAggregate(groupBy=[a1, c], auxGrouping=[b1], select=[a1, c, b1, Partial_COUNT(d1) AS count$0])
          +- Calc(select=[a1, b1, w0$o0 AS c, d1])
             +- OverAggregate(partitionBy=[c1], window#0=[COUNT(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[a1, b1, c1, d1, w0$o0])
-               +- Sort(orderBy=[c1 ASC])
-                  +- Exchange(distribution=[hash[c1]])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[c1 ASC])
+                     +- Exchange(distribution=[hash[c1]])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
 ]]>
     </Resource>
   </TestCase>
@@ -285,13 +289,14 @@ LogicalAggregate(group=[{0, 1, 2, 3}], EXPR$4=[COUNT($4)])
       <![CDATA[
 Calc(select=[a1, b1, a2, b2, EXPR$4])
 +- HashAggregate(isMerge=[false], groupBy=[b2], auxGrouping=[a1, b1, a2], select=[b2, a1, b1, a2, COUNT(c1) AS EXPR$4])
-   +- HashJoin(joinType=[RightOuterJoin], where=[(a1 = b2)], select=[a1, b1, c1, a2, b2], build=[right])
-      :- Exchange(distribution=[hash[a1]])
-      :  +- Calc(select=[a1, b1, c1])
-      :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
-      +- Exchange(distribution=[hash[b2]])
-         +- Calc(select=[a2, b2])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(a2, b2, c2)]]], fields=[a2, b2, c2])
+   +- Exchange(distribution=[keep_input_as_is[hash[b2]]])
+      +- HashJoin(joinType=[RightOuterJoin], where=[(a1 = b2)], select=[a1, b1, c1, a2, b2], build=[right])
+         :- Exchange(distribution=[hash[a1]])
+         :  +- Calc(select=[a1, b1, c1])
+         :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
+         +- Exchange(distribution=[hash[b2]])
+            +- Calc(select=[a2, b2])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, T2, source: [TestTableSource(a2, b2, c2)]]], fields=[a2, b2, c2])
 ]]>
     </Resource>
   </TestCase>
@@ -312,13 +317,14 @@ LogicalAggregate(group=[{0, 1, 2, 3}], EXPR$4=[COUNT($4)])
       <![CDATA[
 Calc(select=[a1, b1, a3, b3, EXPR$4])
 +- HashAggregate(isMerge=[false], groupBy=[a3, b3], auxGrouping=[a1, b1], select=[a3, b3, a1, b1, COUNT(c1) AS EXPR$4])
-   +- HashJoin(joinType=[RightOuterJoin], where=[(a1 = a3)], select=[a1, b1, c1, a3, b3], build=[right])
-      :- Exchange(distribution=[hash[a1]])
-      :  +- Calc(select=[a1, b1, c1])
-      :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
-      +- Exchange(distribution=[hash[a3]])
-         +- Calc(select=[a3, b3])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, T3, source: [TestTableSource(a3, b3, c3, d3)]]], fields=[a3, b3, c3, d3])
+   +- Exchange(distribution=[keep_input_as_is[hash[a3, b3]]])
+      +- HashJoin(joinType=[RightOuterJoin], where=[(a1 = a3)], select=[a1, b1, c1, a3, b3], build=[right])
+         :- Exchange(distribution=[hash[a1]])
+         :  +- Calc(select=[a1, b1, c1])
+         :     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
+         +- Exchange(distribution=[hash[a3]])
+            +- Calc(select=[a3, b3])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, T3, source: [TestTableSource(a3, b3, c3, d3)]]], fields=[a3, b3, c3, d3])
 ]]>
     </Resource>
   </TestCase>
@@ -410,9 +416,10 @@ Calc(select=[a4, c4, s, EXPR$3])
       +- LocalHashAggregate(groupBy=[a4, s], auxGrouping=[c4], select=[a4, s, c4, Partial_COUNT(b4) AS count$0])
          +- Calc(select=[a4, c4, w$start AS s, CAST((($f2 - (($f3 * $f3) / $f4)) / $f4) AS INTEGER) AS b4])
             +- HashWindowAggregate(groupBy=[a4], auxGrouping=[c4], window=[TumblingGroupWindow('w$, d4, 900000)], properties=[w$start, w$end, w$rowtime], select=[a4, c4 AS $f2, SUM($f4) AS $f2, SUM(b4) AS $f3, COUNT(b4) AS $f4])
-               +- Calc(select=[a4, c4, d4, b4, (b4 * b4) AS $f4])
-                  +- Exchange(distribution=[hash[a4]])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T4, source: [TestTableSource(a4, b4, c4, d4)]]], fields=[a4, b4, c4, d4])
+               +- Exchange(distribution=[keep_input_as_is[hash[a4]]])
+                  +- Calc(select=[a4, c4, d4, b4, (b4 * b4) AS $f4])
+                     +- Exchange(distribution=[hash[a4]])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, T4, source: [TestTableSource(a4, b4, c4, d4)]]], fields=[a4, b4, c4, d4])
 ]]>
     </Resource>
   </TestCase>
@@ -437,9 +444,10 @@ Calc(select=[a4, c4, e, EXPR$3])
       +- LocalHashAggregate(groupBy=[a4, e], auxGrouping=[c4], select=[a4, e, c4, Partial_COUNT(b4) AS count$0])
          +- Calc(select=[a4, c4, w$end AS e, CAST((($f2 - (($f3 * $f3) / $f4)) / $f4) AS INTEGER) AS b4])
             +- HashWindowAggregate(groupBy=[a4], auxGrouping=[c4], window=[TumblingGroupWindow('w$, d4, 900000)], properties=[w$start, w$end, w$rowtime], select=[a4, c4 AS $f2, SUM($f4) AS $f2, SUM(b4) AS $f3, COUNT(b4) AS $f4])
-               +- Calc(select=[a4, c4, d4, b4, (b4 * b4) AS $f4])
-                  +- Exchange(distribution=[hash[a4]])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T4, source: [TestTableSource(a4, b4, c4, d4)]]], fields=[a4, b4, c4, d4])
+               +- Exchange(distribution=[keep_input_as_is[hash[a4]]])
+                  +- Calc(select=[a4, c4, d4, b4, (b4 * b4) AS $f4])
+                     +- Exchange(distribution=[hash[a4]])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, T4, source: [TestTableSource(a4, b4, c4, d4)]]], fields=[a4, b4, c4, d4])
 ]]>
     </Resource>
   </TestCase>
@@ -463,9 +471,10 @@ HashAggregate(isMerge=[true], groupBy=[a4, b4], auxGrouping=[c4], select=[a4, b4
    +- LocalHashAggregate(groupBy=[a4, b4], auxGrouping=[c4], select=[a4, b4, c4, Partial_COUNT(*) AS count1$0])
       +- Calc(select=[a4, c4, CAST((($f2 - (($f3 * $f3) / $f4)) / $f4) AS INTEGER) AS b4])
          +- HashWindowAggregate(groupBy=[a4], auxGrouping=[c4], window=[TumblingGroupWindow('w$, d4, 900000)], select=[a4, c4 AS $f2, SUM($f4) AS $f2, SUM(b4) AS $f3, COUNT(b4) AS $f4])
-            +- Calc(select=[a4, c4, d4, b4, (b4 * b4) AS $f4])
-               +- Exchange(distribution=[hash[a4]])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, T4, source: [TestTableSource(a4, b4, c4, d4)]]], fields=[a4, b4, c4, d4])
+            +- Exchange(distribution=[keep_input_as_is[hash[a4]]])
+               +- Calc(select=[a4, c4, d4, b4, (b4 * b4) AS $f4])
+                  +- Exchange(distribution=[hash[a4]])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, T4, source: [TestTableSource(a4, b4, c4, d4)]]], fields=[a4, b4, c4, d4])
 ]]>
     </Resource>
   </TestCase>
@@ -628,10 +637,12 @@ LogicalAggregate(group=[{0, 1, 2, 3, 4}], EXPR$5=[COUNT()])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[a1], auxGrouping=[b1, c1, d1, m], select=[a1, b1, c1, d1, m, COUNT(*) AS EXPR$5])
-+- SortAggregate(isMerge=[false], groupBy=[a1], auxGrouping=[b1, c1], select=[a1, b1, c1, COUNT(d1) AS d1, MAX(d1) AS m])
-   +- Sort(orderBy=[a1 ASC])
-      +- Exchange(distribution=[hash[a1]])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
++- Exchange(distribution=[forward])
+   +- SortAggregate(isMerge=[false], groupBy=[a1], auxGrouping=[b1, c1], select=[a1, b1, c1, COUNT(d1) AS d1, MAX(d1) AS m])
+      +- Exchange(distribution=[forward])
+         +- Sort(orderBy=[a1 ASC])
+            +- Exchange(distribution=[hash[a1]])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, T1, source: [TestTableSource(a1, b1, c1, d1)]]], fields=[a1, b1, c1, d1])
 ]]>
     </Resource>
   </TestCase>
@@ -649,10 +660,11 @@ LogicalAggregate(group=[{0, 1, 2, 3, 4}], EXPR$5=[COUNT()])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashAggregate(isMerge=[false], groupBy=[a3, b3], auxGrouping=[c, s, a], select=[a3, b3, c, s, a, COUNT(*) AS EXPR$5])
-+- HashAggregate(isMerge=[true], groupBy=[a3, b3], select=[a3, b3, Final_COUNT(count$0) AS c, Final_SUM(sum$1) AS s, Final_AVG(sum$2, count$3) AS a])
-   +- Exchange(distribution=[hash[a3, b3]])
-      +- LocalHashAggregate(groupBy=[a3, b3], select=[a3, b3, Partial_COUNT(c3) AS count$0, Partial_SUM(d3) AS sum$1, Partial_AVG(d3) AS (sum$2, count$3)])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, T3, source: [TestTableSource(a3, b3, c3, d3)]]], fields=[a3, b3, c3, d3])
++- Exchange(distribution=[keep_input_as_is[hash[a3, b3]]])
+   +- HashAggregate(isMerge=[true], groupBy=[a3, b3], select=[a3, b3, Final_COUNT(count$0) AS c, Final_SUM(sum$1) AS s, Final_AVG(sum$2, count$3) AS a])
+      +- Exchange(distribution=[hash[a3, b3]])
+         +- LocalHashAggregate(groupBy=[a3, b3], select=[a3, b3, Partial_COUNT(c3) AS count$0, Partial_SUM(d3) AS sum$1, Partial_AVG(d3) AS (sum$2, count$3)])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, T3, source: [TestTableSource(a3, b3, c3, d3)]]], fields=[a3, b3, c3, d3])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/DistinctAggregateTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/DistinctAggregateTest.xml
index ddbd91acb6d..4d372cab8f3 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/DistinctAggregateTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/DistinctAggregateTest.xml
@@ -333,17 +333,19 @@ LogicalAggregate(group=[{0}], EXPR$1=[MAX($1)], EXPR$2=[MAX($1) FILTER $2], EXPR
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[true], groupBy=[d], select=[d, Final_MIN(min$0) AS EXPR$1, Final_MIN(min$1) AS EXPR$2, Final_COUNT(count$2) AS EXPR$3, Final_COUNT(count$3) AS EXPR$4, Final_COUNT(count$4) AS EXPR$5])
-+- Sort(orderBy=[d ASC])
-   +- Exchange(distribution=[hash[d]])
-      +- LocalSortAggregate(groupBy=[d], select=[d, Partial_MIN(EXPR$1) FILTER $g_15 AS min$0, Partial_MIN(EXPR$2) FILTER $g_15 AS min$1, Partial_COUNT(c) FILTER $g_7 AS count$2, Partial_COUNT(c) FILTER $g_3 AS count$3, Partial_COUNT(b) FILTER $g_12 AS count$4])
-         +- Calc(select=[d, c, b, EXPR$1, EXPR$2, ((CASE(($e = 3), 3, ($e = 7), 7, ($e = 12), 12, 15) = 3) AND $f4 IS TRUE) AS $g_3, (CASE(($e = 3), 3, ($e = 7), 7, ($e = 12), 12, 15) = 7) AS $g_7, ((CASE(($e = 3), 3, ($e = 7), 7, ($e = 12), 12, 15) = 12) AND $f6 IS TRUE) AS $g_12, (CASE(($e = 3), 3, ($e = 7), 7, ($e = 12), 12, 15) = 15) AS $g_15])
-            +- Sort(orderBy=[d ASC])
-               +- SortAggregate(isMerge=[false], groupBy=[d, c, $f4, b, $f6, $e], select=[d, c, $f4, b, $f6, $e, MAX(e) AS EXPR$1, MAX(e) FILTER $f2 AS EXPR$2])
-                  +- Sort(orderBy=[d ASC, c ASC, $f4 ASC, b ASC, $f6 ASC, $e ASC])
-                     +- Exchange(distribution=[hash[d, c, $f4, b, $f6, $e]])
-                        +- Expand(projects=[{d, e, $f2, c, $f4, null AS b, null AS $f6, 3 AS $e}, {d, e, $f2, c, null AS $f4, null AS b, null AS $f6, 7 AS $e}, {d, e, $f2, null AS c, null AS $f4, b, $f6, 12 AS $e}, {d, e, $f2, null AS c, null AS $f4, null AS b, null AS $f6, 15 AS $e}])
-                           +- Calc(select=[d, e, (a < 10) IS TRUE AS $f2, c, (a > 5) IS TRUE AS $f4, b, (b > 3) IS TRUE AS $f6])
-                              +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, c, d, e)]]], fields=[a, b, c, d, e])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[d ASC])
+      +- Exchange(distribution=[hash[d]])
+         +- LocalSortAggregate(groupBy=[d], select=[d, Partial_MIN(EXPR$1) FILTER $g_15 AS min$0, Partial_MIN(EXPR$2) FILTER $g_15 AS min$1, Partial_COUNT(c) FILTER $g_7 AS count$2, Partial_COUNT(c) FILTER $g_3 AS count$3, Partial_COUNT(b) FILTER $g_12 AS count$4])
+            +- Calc(select=[d, c, b, EXPR$1, EXPR$2, ((CASE(($e = 3), 3, ($e = 7), 7, ($e = 12), 12, 15) = 3) AND $f4 IS TRUE) AS $g_3, (CASE(($e = 3), 3, ($e = 7), 7, ($e = 12), 12, 15) = 7) AS $g_7, ((CASE(($e = 3), 3, ($e = 7), 7, ($e = 12), 12, 15) = 12) AND $f6 IS TRUE) AS $g_12, (CASE(($e = 3), 3, ($e = 7), 7, ($e = 12), 12, 15) = 15) AS $g_15])
+               +- Sort(orderBy=[d ASC])
+                  +- SortAggregate(isMerge=[false], groupBy=[d, c, $f4, b, $f6, $e], select=[d, c, $f4, b, $f6, $e, MAX(e) AS EXPR$1, MAX(e) FILTER $f2 AS EXPR$2])
+                     +- Exchange(distribution=[forward])
+                        +- Sort(orderBy=[d ASC, c ASC, $f4 ASC, b ASC, $f6 ASC, $e ASC])
+                           +- Exchange(distribution=[hash[d, c, $f4, b, $f6, $e]])
+                              +- Expand(projects=[{d, e, $f2, c, $f4, null AS b, null AS $f6, 3 AS $e}, {d, e, $f2, c, null AS $f4, null AS b, null AS $f6, 7 AS $e}, {d, e, $f2, null AS c, null AS $f4, b, $f6, 12 AS $e}, {d, e, $f2, null AS c, null AS $f4, null AS b, null AS $f6, 15 AS $e}])
+                                 +- Calc(select=[d, e, (a < 10) IS TRUE AS $f2, c, (a > 5) IS TRUE AS $f4, b, (b > 3) IS TRUE AS $f6])
+                                    +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, c, d, e)]]], fields=[a, b, c, d, e])
 ]]>
     </Resource>
   </TestCase>
@@ -416,17 +418,19 @@ LogicalAggregate(group=[{0}], EXPR$1=[COUNT(DISTINCT $1)], EXPR$2=[COUNT(DISTINC
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[true], groupBy=[d], select=[d, Final_COUNT(count$0) AS EXPR$1, Final_COUNT(count$1) AS EXPR$2, Final_MIN(min$2) AS EXPR$3, Final_MIN(min$3) AS EXPR$4])
-+- Sort(orderBy=[d ASC])
-   +- Exchange(distribution=[hash[d]])
-      +- LocalSortAggregate(groupBy=[d], select=[d, Partial_COUNT(c) FILTER $g_1 AS count$0, Partial_COUNT(c) FILTER $g_0 AS count$1, Partial_MIN(EXPR$3) FILTER $g_3 AS min$2, Partial_MIN(EXPR$4) FILTER $g_3 AS min$3])
-         +- Calc(select=[d, c, EXPR$3, EXPR$4, ((CASE(($e = 0), 0, ($e = 1), 1, 3) = 0) AND $f2 IS TRUE) AS $g_0, (CASE(($e = 0), 0, ($e = 1), 1, 3) = 1) AS $g_1, (CASE(($e = 0), 0, ($e = 1), 1, 3) = 3) AS $g_3])
-            +- Sort(orderBy=[d ASC])
-               +- SortAggregate(isMerge=[false], groupBy=[d, c, $f2, $e], select=[d, c, $f2, $e, MAX(e) AS EXPR$3, MIN(e) AS EXPR$4])
-                  +- Sort(orderBy=[d ASC, c ASC, $f2 ASC, $e ASC])
-                     +- Exchange(distribution=[hash[d, c, $f2, $e]])
-                        +- Expand(projects=[{d, c, $f2, e, 0 AS $e}, {d, c, null AS $f2, e, 1 AS $e}, {d, null AS c, null AS $f2, e, 3 AS $e}])
-                           +- Calc(select=[d, c, (a > 0) IS TRUE AS $f2, e])
-                              +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, c, d, e)]]], fields=[a, b, c, d, e])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[d ASC])
+      +- Exchange(distribution=[hash[d]])
+         +- LocalSortAggregate(groupBy=[d], select=[d, Partial_COUNT(c) FILTER $g_1 AS count$0, Partial_COUNT(c) FILTER $g_0 AS count$1, Partial_MIN(EXPR$3) FILTER $g_3 AS min$2, Partial_MIN(EXPR$4) FILTER $g_3 AS min$3])
+            +- Calc(select=[d, c, EXPR$3, EXPR$4, ((CASE(($e = 0), 0, ($e = 1), 1, 3) = 0) AND $f2 IS TRUE) AS $g_0, (CASE(($e = 0), 0, ($e = 1), 1, 3) = 1) AS $g_1, (CASE(($e = 0), 0, ($e = 1), 1, 3) = 3) AS $g_3])
+               +- Sort(orderBy=[d ASC])
+                  +- SortAggregate(isMerge=[false], groupBy=[d, c, $f2, $e], select=[d, c, $f2, $e, MAX(e) AS EXPR$3, MIN(e) AS EXPR$4])
+                     +- Exchange(distribution=[forward])
+                        +- Sort(orderBy=[d ASC, c ASC, $f2 ASC, $e ASC])
+                           +- Exchange(distribution=[hash[d, c, $f2, $e]])
+                              +- Expand(projects=[{d, c, $f2, e, 0 AS $e}, {d, c, null AS $f2, e, 1 AS $e}, {d, null AS c, null AS $f2, e, 3 AS $e}])
+                                 +- Calc(select=[d, c, (a > 0) IS TRUE AS $f2, e])
+                                    +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, c, d, e)]]], fields=[a, b, c, d, e])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/GroupWindowTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/GroupWindowTest.xml
index 7f70fc3896c..42c6213691b 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/GroupWindowTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/GroupWindowTest.xml
@@ -549,9 +549,10 @@ LogicalProject(c=[$2], EXPR$1=[HOP_END($0)], EXPR$2=[HOP_START($0)], EXPR$3=[HOP
       <![CDATA[
 Calc(select=[c, w$end AS EXPR$1, w$start AS EXPR$2, w$rowtime AS EXPR$3, sumA, avgB])
 +- SortWindowAggregate(groupBy=[c, d], window=[SlidingGroupWindow('w$, ts, 10800000, 3600000)], properties=[w$start, w$end, w$rowtime], select=[c, d, SUM(a) AS sumA, AVG(b) AS avgB])
-   +- Sort(orderBy=[c ASC, d ASC, ts ASC])
-      +- Exchange(distribution=[hash[c, d]])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, c, d, ts)]]], fields=[a, b, c, d, ts])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, d ASC, ts ASC])
+         +- Exchange(distribution=[hash[c, d]])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, c, d, ts)]]], fields=[a, b, c, d, ts])
 ]]>
     </Resource>
   </TestCase>
@@ -818,10 +819,11 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[b], window=[SlidingGroupWindow('w$, ts, 3600000, 3000)], select=[b, COUNT(c) AS EXPR$0])
-   +- Sort(orderBy=[b ASC, ts ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- Calc(select=[b, ts, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, ts ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- Calc(select=[b, ts, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -864,12 +866,14 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[a], window=[SlidingGroupWindow('w$, ts, 3600000, 3000)], select=[a, Final_MAX(max$0) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, assignedPane$ ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- LocalSortWindowAggregate(groupBy=[a], window=[SlidingGroupWindow('w$, ts, 3600000, 3000)], select=[a, Partial_MAX(c) AS max$0])
-            +- Sort(orderBy=[a ASC, ts ASC])
-               +- Calc(select=[a, ts, c])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, assignedPane$ ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- LocalSortWindowAggregate(groupBy=[a], window=[SlidingGroupWindow('w$, ts, 3600000, 3000)], select=[a, Partial_MAX(c) AS max$0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[a ASC, ts ASC])
+                     +- Calc(select=[a, ts, c])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -889,10 +893,11 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[a], window=[SlidingGroupWindow('w$, ts, 3600000, 3000)], select=[a, MAX(c) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, ts ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- Calc(select=[a, ts, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, ts ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- Calc(select=[a, ts, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -912,12 +917,14 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[a], window=[SlidingGroupWindow('w$, ts, 3600000, 3000)], select=[a, Final_MAX(max$0) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, assignedPane$ ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- LocalSortWindowAggregate(groupBy=[a], window=[SlidingGroupWindow('w$, ts, 3600000, 3000)], select=[a, Partial_MAX(c) AS max$0])
-            +- Sort(orderBy=[a ASC, ts ASC])
-               +- Calc(select=[a, ts, c])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, assignedPane$ ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- LocalSortWindowAggregate(groupBy=[a], window=[SlidingGroupWindow('w$, ts, 3600000, 3000)], select=[a, Partial_MAX(c) AS max$0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[a ASC, ts ASC])
+                     +- Calc(select=[a, ts, c])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -937,10 +944,11 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[b], window=[SlidingGroupWindow('w$, ts, 1000, 111)], select=[b, MAX(c) AS EXPR$0])
-   +- Sort(orderBy=[b ASC, ts ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- Calc(select=[b, ts, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, ts ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- Calc(select=[b, ts, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -960,10 +968,11 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[b], window=[SlidingGroupWindow('w$, ts, 1000, 111)], select=[b, MAX(c) AS EXPR$0])
-   +- Sort(orderBy=[b ASC, ts ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- Calc(select=[b, ts, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, ts ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- Calc(select=[b, ts, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -983,10 +992,11 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[b], window=[SlidingGroupWindow('w$, ts, 1000, 111)], select=[b, MAX(c) AS EXPR$0])
-   +- Sort(orderBy=[b ASC, ts ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- Calc(select=[b, ts, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, ts ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- Calc(select=[b, ts, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -1006,9 +1016,10 @@ LogicalProject(EXPR$0=[$3])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[a, d], window=[SlidingGroupWindow('w$, b, 3600000, 3000)], select=[a, d, countFun(c) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, d ASC, b ASC])
-      +- Exchange(distribution=[hash[a, d]])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, d ASC, b ASC])
+         +- Exchange(distribution=[hash[a, d]])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
 ]]>
     </Resource>
   </TestCase>
@@ -1028,9 +1039,10 @@ LogicalProject(EXPR$0=[$3])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[a, d], window=[SlidingGroupWindow('w$, b, 3600000, 3000)], select=[a, d, countFun(c) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, d ASC, b ASC])
-      +- Exchange(distribution=[hash[a, d]])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, d ASC, b ASC])
+         +- Exchange(distribution=[hash[a, d]])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
 ]]>
     </Resource>
   </TestCase>
@@ -1050,11 +1062,13 @@ LogicalProject(EXPR$0=[$3])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[a, d], window=[SlidingGroupWindow('w$, b, 3600000, 3000)], select=[a, d, Final_countFun(EXPR$0) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, d ASC, assignedPane$ ASC])
-      +- Exchange(distribution=[hash[a, d]])
-         +- LocalSortWindowAggregate(groupBy=[a, d], window=[SlidingGroupWindow('w$, b, 3600000, 3000)], select=[a, d, Partial_countFun(c) AS EXPR$0])
-            +- Sort(orderBy=[a ASC, d ASC, b ASC])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, d ASC, assignedPane$ ASC])
+         +- Exchange(distribution=[hash[a, d]])
+            +- LocalSortWindowAggregate(groupBy=[a, d], window=[SlidingGroupWindow('w$, b, 3600000, 3000)], select=[a, d, Partial_countFun(c) AS EXPR$0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[a ASC, d ASC, b ASC])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
 ]]>
     </Resource>
   </TestCase>
@@ -1074,10 +1088,11 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[a], window=[SlidingGroupWindow('w$, ts, 3600000, 3000)], select=[a, COUNT(c) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, ts ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- Calc(select=[a, ts, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, ts ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- Calc(select=[a, ts, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -1253,12 +1268,14 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[a], window=[TumblingGroupWindow('w$, ts, 3000)], select=[a, Final_MAX(max$0) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, assignedWindow$ ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- LocalSortWindowAggregate(groupBy=[a], window=[TumblingGroupWindow('w$, ts, 3000)], select=[a, Partial_MAX(c) AS max$0])
-            +- Sort(orderBy=[a ASC, ts ASC])
-               +- Calc(select=[a, ts, c])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, assignedWindow$ ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- LocalSortWindowAggregate(groupBy=[a], window=[TumblingGroupWindow('w$, ts, 3000)], select=[a, Partial_MAX(c) AS max$0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[a ASC, ts ASC])
+                     +- Calc(select=[a, ts, c])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -1278,10 +1295,11 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[a], window=[TumblingGroupWindow('w$, ts, 3000)], select=[a, MAX(c) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, ts ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- Calc(select=[a, ts, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, ts ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- Calc(select=[a, ts, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -1301,12 +1319,14 @@ LogicalProject(EXPR$0=[$2])
       <![CDATA[
 Calc(select=[EXPR$0])
 +- SortWindowAggregate(groupBy=[a], window=[TumblingGroupWindow('w$, ts, 3000)], select=[a, Final_MAX(max$0) AS EXPR$0])
-   +- Sort(orderBy=[a ASC, assignedWindow$ ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- LocalSortWindowAggregate(groupBy=[a], window=[TumblingGroupWindow('w$, ts, 3000)], select=[a, Partial_MAX(c) AS max$0])
-            +- Sort(orderBy=[a ASC, ts ASC])
-               +- Calc(select=[a, ts, c])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, assignedWindow$ ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- LocalSortWindowAggregate(groupBy=[a], window=[TumblingGroupWindow('w$, ts, 3000)], select=[a, Partial_MAX(c) AS max$0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[a ASC, ts ASC])
+                     +- Calc(select=[a, ts, c])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(ts, a, b, c)]]], fields=[ts, a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -1326,9 +1346,10 @@ LogicalProject(EXPR$0=[$3], EXPR$1=[$4])
       <![CDATA[
 Calc(select=[EXPR$0, EXPR$1])
 +- SortWindowAggregate(groupBy=[a, d], window=[TumblingGroupWindow('w$, b, 3000)], select=[a, d, AVG(c) AS EXPR$0, countFun(a) AS EXPR$1])
-   +- Sort(orderBy=[a ASC, d ASC, b ASC])
-      +- Exchange(distribution=[hash[a, d]])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, d ASC, b ASC])
+         +- Exchange(distribution=[hash[a, d]])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
 ]]>
     </Resource>
   </TestCase>
@@ -1348,9 +1369,10 @@ LogicalProject(EXPR$0=[$3], EXPR$1=[$4])
       <![CDATA[
 Calc(select=[EXPR$0, EXPR$1])
 +- SortWindowAggregate(groupBy=[a, d], window=[TumblingGroupWindow('w$, b, 3000)], select=[a, d, AVG(c) AS EXPR$0, countFun(a) AS EXPR$1])
-   +- Sort(orderBy=[a ASC, d ASC, b ASC])
-      +- Exchange(distribution=[hash[a, d]])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, d ASC, b ASC])
+         +- Exchange(distribution=[hash[a, d]])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
 ]]>
     </Resource>
   </TestCase>
@@ -1370,11 +1392,13 @@ LogicalProject(EXPR$0=[$3], EXPR$1=[$4])
       <![CDATA[
 Calc(select=[EXPR$0, EXPR$1])
 +- SortWindowAggregate(groupBy=[a, d], window=[TumblingGroupWindow('w$, b, 3000)], select=[a, d, Final_AVG(sum$0, count$1) AS EXPR$0, Final_countFun(EXPR$1) AS EXPR$1])
-   +- Sort(orderBy=[a ASC, d ASC, assignedWindow$ ASC])
-      +- Exchange(distribution=[hash[a, d]])
-         +- LocalSortWindowAggregate(groupBy=[a, d], window=[TumblingGroupWindow('w$, b, 3000)], select=[a, d, Partial_AVG(c) AS (sum$0, count$1), Partial_countFun(a) AS EXPR$1])
-            +- Sort(orderBy=[a ASC, d ASC, b ASC])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC, d ASC, assignedWindow$ ASC])
+         +- Exchange(distribution=[hash[a, d]])
+            +- LocalSortWindowAggregate(groupBy=[a, d], window=[TumblingGroupWindow('w$, b, 3000)], select=[a, d, Partial_AVG(c) AS (sum$0, count$1), Partial_countFun(a) AS EXPR$1])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[a ASC, d ASC, b ASC])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, d)]]], fields=[a, b, c, d])
 ]]>
     </Resource>
   </TestCase>
@@ -1396,9 +1420,10 @@ SortWindowAggregate(window=[TumblingGroupWindow('w$, ts, 240000)], select=[Final
 +- Sort(orderBy=[assignedWindow$ ASC])
    +- Exchange(distribution=[single])
       +- LocalSortWindowAggregate(window=[TumblingGroupWindow('w$, ts, 240000)], select=[Partial_weightedAvg(b, a) AS wAvg])
-         +- Sort(orderBy=[ts ASC])
-            +- Calc(select=[ts, b, a])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, c, d, ts)]]], fields=[a, b, c, d, ts])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[ts ASC])
+               +- Calc(select=[ts, b, a])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, c, d, ts)]]], fields=[a, b, c, d, ts])
 ]]>
     </Resource>
   </TestCase>
@@ -1442,9 +1467,10 @@ SortWindowAggregate(window=[TumblingGroupWindow('w$, ts, 240000)], select=[Final
 +- Sort(orderBy=[assignedWindow$ ASC])
    +- Exchange(distribution=[single])
       +- LocalSortWindowAggregate(window=[TumblingGroupWindow('w$, ts, 240000)], select=[Partial_weightedAvg(b, a) AS wAvg])
-         +- Sort(orderBy=[ts ASC])
-            +- Calc(select=[ts, b, a])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, c, d, ts)]]], fields=[a, b, c, d, ts])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[ts ASC])
+               +- Calc(select=[ts, b, a])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable2, source: [TestTableSource(a, b, c, d, ts)]]], fields=[a, b, c, d, ts])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/GroupingSetsTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/GroupingSetsTest.xml
index bbf10b5d2fd..ba8d992317f 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/GroupingSetsTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/GroupingSetsTest.xml
@@ -293,17 +293,19 @@ LogicalProject(deptno=[$0], gender=[$2], min_name=[$3])
       <![CDATA[
 Calc(select=[deptno, gender, min_name], where=[(($f5 > 2) OR ((gender = 'M') AND (deptno = 10)))])
 +- SortAggregate(isMerge=[true], groupBy=[deptno, gender, deptno0, $e], select=[deptno, gender, deptno0, $e, Final_MIN(min$0) AS min_name, Final_COUNT(count1$1) AS $f5])
-   +- Sort(orderBy=[deptno ASC, gender ASC, deptno0 ASC, $e ASC])
-      +- Exchange(distribution=[hash[deptno, gender, deptno0, $e]])
-         +- LocalSortAggregate(groupBy=[deptno, gender, deptno0, $e], select=[deptno, gender, deptno0, $e, Partial_MIN(ename) AS min$0, Partial_COUNT(*) AS count1$1])
-            +- Sort(orderBy=[deptno ASC, gender ASC, deptno0 ASC, $e ASC])
-               +- Expand(projects=[{ename, deptno, gender, deptno0, 0 AS $e}, {ename, deptno, gender, null AS deptno0, 1 AS $e}, {ename, deptno, null AS gender, deptno0, 2 AS $e}, {ename, deptno, null AS gender, null AS deptno0, 3 AS $e}, {ename, null AS deptno, gender, deptno0, 4 AS $e}, {ename, null AS deptno, gender, null AS deptno0, 5 AS $e}, {ename, null AS deptno, null AS gender, deptno0, 6 AS $e}, {ename, null AS deptno, null AS gender, null AS deptno0, 7 AS $e}])
-                  +- HashJoin(joinType=[InnerJoin], where=[(deptno = deptno0)], select=[ename, deptno, gender, deptno0], build=[right])
-                     :- Exchange(distribution=[hash[deptno]])
-                     :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, emp, source: [TestTableSource(ename, deptno, gender)]]], fields=[ename, deptno, gender])
-                     +- Exchange(distribution=[hash[deptno]])
-                        +- Calc(select=[deptno])
-                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, dept, source: [TestTableSource(deptno, dname)]]], fields=[deptno, dname])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[deptno ASC, gender ASC, deptno0 ASC, $e ASC])
+         +- Exchange(distribution=[hash[deptno, gender, deptno0, $e]])
+            +- LocalSortAggregate(groupBy=[deptno, gender, deptno0, $e], select=[deptno, gender, deptno0, $e, Partial_MIN(ename) AS min$0, Partial_COUNT(*) AS count1$1])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[deptno ASC, gender ASC, deptno0 ASC, $e ASC])
+                     +- Expand(projects=[{ename, deptno, gender, deptno0, 0 AS $e}, {ename, deptno, gender, null AS deptno0, 1 AS $e}, {ename, deptno, null AS gender, deptno0, 2 AS $e}, {ename, deptno, null AS gender, null AS deptno0, 3 AS $e}, {ename, null AS deptno, gender, deptno0, 4 AS $e}, {ename, null AS deptno, gender, null AS deptno0, 5 AS $e}, {ename, null AS deptno, null AS gender, deptno0, 6 AS $e}, {ename, null AS deptno, null AS gender, null AS deptno0, 7 AS $e}])
+                        +- HashJoin(joinType=[InnerJoin], where=[(deptno = deptno0)], select=[ename, deptno, gender, deptno0], build=[right])
+                           :- Exchange(distribution=[hash[deptno]])
+                           :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, emp, source: [TestTableSource(ename, deptno, gender)]]], fields=[ename, deptno, gender])
+                           +- Exchange(distribution=[hash[deptno]])
+                              +- Calc(select=[deptno])
+                                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, dept, source: [TestTableSource(deptno, dname)]]], fields=[deptno, dname])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/OverAggregateTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/OverAggregateTest.xml
index c58b35754ae..909efe170f7 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/OverAggregateTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/OverAggregateTest.xml
@@ -38,14 +38,18 @@ LogicalProject(EXPR$0=[CASE(>(COUNT($0) OVER (PARTITION BY $1 ORDER BY $0 NULLS
       <![CDATA[
 Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS EXPR$0, w1$o0 AS EXPR$1, CAST((CASE((w2$o0 > 0), w2$o1, null:INTEGER) / w2$o0) AS INTEGER) AS EXPR$2, w0$o2 AS EXPR$3, w2$o2 AS EXPR$4])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(a) AS w2$o0, $SUM0(a) AS w2$o1, MIN(a) AS w2$o2 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o1, w0$o2, w1$o0, w2$o0, w2$o1, w2$o2])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- OverAggregate(partitionBy=[b], orderBy=[c ASC], window#0=[MAX(a) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o1, w0$o2, w1$o0])
-            +- Sort(orderBy=[b ASC, c ASC])
-               +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#1=[RANK(*) AS w0$o2 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o1, w0$o2])
-                  +- Sort(orderBy=[b ASC, a ASC])
-                     +- Exchange(distribution=[hash[b]])
-                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- OverAggregate(partitionBy=[b], orderBy=[c ASC], window#0=[MAX(a) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o1, w0$o2, w1$o0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[b ASC, c ASC])
+                     +- Exchange(distribution=[keep_input_as_is[hash[b]]])
+                        +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#1=[RANK(*) AS w0$o2 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o1, w0$o2])
+                           +- Exchange(distribution=[forward])
+                              +- Sort(orderBy=[b ASC, a ASC])
+                                 +- Exchange(distribution=[hash[b]])
+                                    +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -71,17 +75,21 @@ LogicalProject(EXPR$0=[CASE(>(COUNT($0) OVER (PARTITION BY $1 ORDER BY $2 NULLS
       <![CDATA[
 Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS EXPR$0, w1$o0 AS EXPR$1, w2$o0 AS EXPR$2, w0$o2 AS EXPR$3, CAST((CASE((w3$o0 > 0), w3$o1, null:INTEGER) / w3$o0) AS INTEGER) AS EXPR$4])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[MAX(a) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o2, w1$o0, w0$o1, w3$o0, w3$o1, w2$o0, w0$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- OverAggregate(partitionBy=[b], orderBy=[c ASC], window#0=[COUNT(a) AS w3$o0, $SUM0(a) AS w3$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#1=[RANK(*) AS w2$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o2, w1$o0, w0$o1, w3$o0, w3$o1, w2$o0])
-            +- Sort(orderBy=[b ASC, c ASC])
-               +- Exchange(distribution=[hash[b]])
-                  +- OverAggregate(orderBy=[c ASC, a ASC], window#0=[MIN(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o2, w1$o0, w0$o1])
-                     +- Sort(orderBy=[c ASC, a ASC])
-                        +- OverAggregate(orderBy=[b ASC], window#0=[COUNT(a) AS w0$o2, $SUM0(a) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o2, w1$o0])
-                           +- Sort(orderBy=[b ASC])
-                              +- Exchange(distribution=[single])
-                                 +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- OverAggregate(partitionBy=[b], orderBy=[c ASC], window#0=[COUNT(a) AS w3$o0, $SUM0(a) AS w3$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#1=[RANK(*) AS w2$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o2, w1$o0, w0$o1, w3$o0, w3$o1, w2$o0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[b ASC, c ASC])
+                     +- Exchange(distribution=[hash[b]])
+                        +- OverAggregate(orderBy=[c ASC, a ASC], window#0=[MIN(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o2, w1$o0, w0$o1])
+                           +- Exchange(distribution=[forward])
+                              +- Sort(orderBy=[c ASC, a ASC])
+                                 +- Exchange(distribution=[forward])
+                                    +- OverAggregate(orderBy=[b ASC], window#0=[COUNT(a) AS w0$o2, $SUM0(a) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o2, w1$o0])
+                                       +- Sort(orderBy=[b ASC])
+                                          +- Exchange(distribution=[single])
+                                             +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -104,12 +112,14 @@ LogicalProject(EXPR$0=[CASE(>(COUNT($0) OVER (PARTITION BY $1 ORDER BY $0 NULLS
       <![CDATA[
 Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS EXPR$0, w1$o0 AS EXPR$1])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[MAX(a) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o1, w1$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o1])
-            +- Sort(orderBy=[b ASC, a ASC])
-               +- Exchange(distribution=[hash[b]])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w0$o1])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[b ASC, a ASC])
+                     +- Exchange(distribution=[hash[b]])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -135,11 +145,13 @@ LogicalProject(EXPR$0=[COUNT() OVER (PARTITION BY $2 ORDER BY $0 NULLS FIRST RAN
       <![CDATA[
 Calc(select=[w0$o0 AS EXPR$0, CASE((w1$o0 > 0), w1$o1, null:INTEGER) AS EXPR$1, w2$o0 AS EXPR$2, CASE((w3$o0 > 0), w3$o1, null:INTEGER) AS EXPR$3, w4$o0 AS EXPR$4])
 +- OverAggregate(partitionBy=[c], orderBy=[c ASC], window#0=[COUNT(*) AS w4$o0 ROWS BETWEEN 1 PRECEDING AND 10 FOLLOWING], select=[a, c, w0$o0, w1$o0, w1$o1, w3$o1, w2$o0, w3$o0, w4$o0])
-   +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(*) AS w0$o0 RANG BETWEEN -1 PRECEDING AND 10 FOLLOWING], window#1=[COUNT(a) AS w1$o0, $SUM0(a) AS w1$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#2=[COUNT(a) AS w3$o1, $SUM0(a) AS w2$o0 RANG BETWEEN 1 PRECEDING AND 10 FOLLOWING], window#3=[RANK(*) AS w3$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, c, w0$o0, w1$o0, w1$o1, w3$o1, w2$o0, w3$o0])
-      +- Sort(orderBy=[c ASC, a ASC])
-         +- Exchange(distribution=[hash[c]])
-            +- Calc(select=[a, c])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(*) AS w0$o0 RANG BETWEEN -1 PRECEDING AND 10 FOLLOWING], window#1=[COUNT(a) AS w1$o0, $SUM0(a) AS w1$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#2=[COUNT(a) AS w3$o1, $SUM0(a) AS w2$o0 RANG BETWEEN 1 PRECEDING AND 10 FOLLOWING], window#3=[RANK(*) AS w3$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, c, w0$o0, w1$o0, w1$o1, w3$o1, w2$o0, w3$o0])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[c ASC, a ASC])
+               +- Exchange(distribution=[hash[c]])
+                  +- Calc(select=[a, c])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -161,10 +173,11 @@ LogicalProject(c=[$2], EXPR$1=[COUNT() OVER (PARTITION BY $2 ORDER BY $0 NULLS F
       <![CDATA[
 Calc(select=[c, w0$o0 AS $1])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(*) AS w0$o0 ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING], select=[a, c, w0$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- Calc(select=[a, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- Calc(select=[a, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -186,10 +199,11 @@ LogicalProject(c=[$2], EXPR$1=[COUNT() OVER (PARTITION BY $2 ORDER BY $0 NULLS F
       <![CDATA[
 Calc(select=[c, w0$o0 AS $1])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(*) AS w0$o0 ROWS BETWEEN 0 PRECEDING AND CURRENT ROW], select=[a, c, w0$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- Calc(select=[a, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- Calc(select=[a, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -211,10 +225,11 @@ LogicalProject(c=[$2], EXPR$1=[COUNT() OVER (PARTITION BY $2 ORDER BY $0 NULLS F
       <![CDATA[
 Calc(select=[c, w0$o0 AS $1])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(*) AS w0$o0 ROWS BETWEEN CURRENT ROW AND 0 FOLLOWING], select=[a, c, w0$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- Calc(select=[a, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- Calc(select=[a, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -236,10 +251,11 @@ LogicalProject(EXPR$0=[COUNT() OVER (PARTITION BY $2 ORDER BY $0 NULLS FIRST RAN
       <![CDATA[
 Calc(select=[w0$o0 AS $0])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(*) AS w0$o0 RANG BETWEEN -1 PRECEDING AND 10 FOLLOWING], select=[a, c, w0$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- Calc(select=[a, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- Calc(select=[a, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -256,10 +272,11 @@ LogicalProject(c=[$2], EXPR$1=[COUNT() OVER (PARTITION BY $2)])
     <Resource name="optimized exec plan">
       <![CDATA[
 OverAggregate(partitionBy=[c], window#0=[COUNT(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[c, w0$o0])
-+- Sort(orderBy=[c ASC])
-   +- Exchange(distribution=[hash[c]])
-      +- Calc(select=[c])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[c ASC])
+      +- Exchange(distribution=[hash[c]])
+         +- Calc(select=[c])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -320,10 +337,11 @@ LogicalProject(EXPR$0=[COUNT() OVER (PARTITION BY $2 ORDER BY $0 NULLS FIRST RAN
       <![CDATA[
 Calc(select=[w0$o0 AS $0])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(*) AS w0$o0 RANG BETWEEN -1 PRECEDING AND 10 FOLLOWING], select=[a, c, w0$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- Calc(select=[a, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- Calc(select=[a, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -345,10 +363,11 @@ LogicalProject(EXPR$0=[COUNT() OVER (PARTITION BY $2 ORDER BY $0 NULLS FIRST RAN
       <![CDATA[
 Calc(select=[w0$o0 AS $0])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(*) AS w0$o0 RANG BETWEEN -1 FOLLOWING AND 10 FOLLOWING], select=[a, c, w0$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- Calc(select=[a, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- Calc(select=[a, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -366,10 +385,11 @@ LogicalProject(EXPR$0=[RANK() OVER (PARTITION BY $2 ORDER BY $0 NULLS FIRST, $2
       <![CDATA[
 Calc(select=[w0$o0 AS $0])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC, c ASC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, c, w0$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- Calc(select=[a, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- Calc(select=[a, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -411,10 +431,11 @@ LogicalProject(EXPR$0=[CASE(>(COUNT($0) OVER (PARTITION BY $2 ORDER BY $0 NULLS
       <![CDATA[
 Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS EXPR$0, w0$o2 AS EXPR$1])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1, COUNT(1) AS w0$o2 RANG BETWEEN -1 FOLLOWING AND 10 FOLLOWING], select=[a, c, w0$o0, w0$o1, w0$o2])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- Calc(select=[a, c])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- Calc(select=[a, c])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -437,13 +458,14 @@ LogicalProject(EXPR$0=[COUNT(2) OVER (ORDER BY $0 NULLS FIRST)], EXPR$1=[COUNT(1
       <![CDATA[
 Calc(select=[w0$o0 AS $0, w1$o0 AS $1])
 +- OverAggregate(partitionBy=[c], orderBy=[a ASC], window#0=[COUNT(1) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, c, w0$o0, w1$o0])
-   +- Sort(orderBy=[c ASC, a ASC])
-      +- Exchange(distribution=[hash[c]])
-         +- OverAggregate(orderBy=[a ASC], window#0=[COUNT(2) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, c, w0$o0])
-            +- Sort(orderBy=[a ASC])
-               +- Exchange(distribution=[single])
-                  +- Calc(select=[a, c])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[c ASC, a ASC])
+         +- Exchange(distribution=[hash[c]])
+            +- OverAggregate(orderBy=[a ASC], window#0=[COUNT(2) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, c, w0$o0])
+               +- Sort(orderBy=[a ASC])
+                  +- Exchange(distribution=[single])
+                     +- Calc(select=[a, c])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
 	</Resource>
   </TestCase>
@@ -469,12 +491,16 @@ LogicalProject(EXPR$0=[CASE(>(COUNT($0) OVER (PARTITION BY $1 ORDER BY $2 NULLS
       <![CDATA[
 Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS EXPR$0, w1$o0 AS EXPR$1, CAST((CASE((w2$o0 > 0), w2$o1, null:INTEGER) / w2$o0) AS INTEGER) AS EXPR$2, w0$o2 AS EXPR$3, w1$o1 AS EXPR$4])
 +- OverAggregate(partitionBy=[b], orderBy=[c ASC], window#0=[COUNT(a) AS w2$o0, $SUM0(a) AS w2$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#1=[RANK(*) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o1, w0$o2, w1$o1, w0$o0, w2$o0, w2$o1, w1$o0])
-   +- Sort(orderBy=[b ASC, c ASC])
-      +- OverAggregate(partitionBy=[b], orderBy=[b ASC], window#0=[MAX(a) AS w1$o1, MIN(a) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o1, w0$o2, w1$o1, w0$o0])
-         +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[COUNT(a) AS w0$o1, $SUM0(a) AS w0$o2 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o1, w0$o2])
-            +- Sort(orderBy=[b ASC, a ASC])
-               +- Exchange(distribution=[hash[b]])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, c ASC])
+         +- Exchange(distribution=[keep_input_as_is[hash[b]]])
+            +- OverAggregate(partitionBy=[b], orderBy=[b ASC], window#0=[MAX(a) AS w1$o1, MIN(a) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o1, w0$o2, w1$o1, w0$o0])
+               +- Exchange(distribution=[forward])
+                  +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[COUNT(a) AS w0$o1, $SUM0(a) AS w0$o2 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o1, w0$o2])
+                     +- Exchange(distribution=[forward])
+                        +- Sort(orderBy=[b ASC, a ASC])
+                           +- Exchange(distribution=[hash[b]])
+                              +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -500,14 +526,20 @@ LogicalProject(EXPR$0=[CASE(>(COUNT($0) OVER (PARTITION BY $1 ORDER BY $2 NULLS
       <![CDATA[
 Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS EXPR$0, w1$o0 AS EXPR$1, CAST((CASE((w2$o0 > 0), w2$o1, null:INTEGER) / w2$o0) AS INTEGER) AS EXPR$2, w3$o0 AS EXPR$3, w4$o0 AS EXPR$4])
 +- OverAggregate(partitionBy=[b], orderBy=[c ASC], window#0=[COUNT(a) AS w1$o0, $SUM0(a) AS w3$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w2$o0, w0$o0, w2$o1, w4$o0, w0$o1, w1$o0, w3$o0])
-   +- Sort(orderBy=[b ASC, c ASC])
-      +- OverAggregate(partitionBy=[b], orderBy=[b ASC], window#0=[MIN(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w2$o0, w0$o0, w2$o1, w4$o0, w0$o1])
-         +- OverAggregate(partitionBy=[b], orderBy=[a ASC, c ASC], window#0=[COUNT(a) AS w2$o1, $SUM0(a) AS w4$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w2$o0, w0$o0, w2$o1, w4$o0])
-            +- Sort(orderBy=[b ASC, a ASC, c ASC])
-               +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[MAX(a) AS w2$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#1=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w2$o0, w0$o0])
-                  +- Sort(orderBy=[b ASC, a ASC])
-                     +- Exchange(distribution=[hash[b]])
-                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, c ASC])
+         +- Exchange(distribution=[keep_input_as_is[hash[b]]])
+            +- OverAggregate(partitionBy=[b], orderBy=[b ASC], window#0=[MIN(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w2$o0, w0$o0, w2$o1, w4$o0, w0$o1])
+               +- Exchange(distribution=[forward])
+                  +- OverAggregate(partitionBy=[b], orderBy=[a ASC, c ASC], window#0=[COUNT(a) AS w2$o1, $SUM0(a) AS w4$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w2$o0, w0$o0, w2$o1, w4$o0])
+                     +- Exchange(distribution=[forward])
+                        +- Sort(orderBy=[b ASC, a ASC, c ASC])
+                           +- Exchange(distribution=[keep_input_as_is[hash[b]]])
+                              +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[MAX(a) AS w2$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#1=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w2$o0, w0$o0])
+                                 +- Exchange(distribution=[forward])
+                                    +- Sort(orderBy=[b ASC, a ASC])
+                                       +- Exchange(distribution=[hash[b]])
+                                          +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -530,10 +562,11 @@ LogicalProject(EXPR$0=[CASE(>(COUNT($0) OVER (PARTITION BY $1 ORDER BY $0 NULLS
       <![CDATA[
 Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS EXPR$0, w0$o2 AS EXPR$1])
 +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1, MAX(a) AS w0$o2 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, w0$o0, w0$o1, w0$o2])
-   +- Sort(orderBy=[b ASC, a ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- Calc(select=[a, b])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, a ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- Calc(select=[a, b])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -559,12 +592,15 @@ LogicalProject(EXPR$0=[CASE(>(COUNT($0) OVER (PARTITION BY $1 ORDER BY $0 NULLS
       <![CDATA[
 Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS EXPR$0, w0$o2 AS EXPR$1, CAST((CASE((w1$o0 > 0), w1$o1, null:INTEGER) / w1$o0) AS INTEGER) AS EXPR$2, w0$o3 AS EXPR$3, w1$o2 AS EXPR$4])
 +- OverAggregate(partitionBy=[b], orderBy=[a DESC], window#0=[COUNT(a) AS w1$o0, $SUM0(a) AS w1$o1, MIN(a) AS w1$o2 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, w0$o0, w0$o1, w0$o2, w0$o3, w1$o0, w1$o1, w1$o2])
-   +- Sort(orderBy=[b ASC, a DESC])
-      +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1, MAX(a) AS w0$o2 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#1=[RANK(*) AS w0$o3 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, w0$o0, w0$o1, w0$o2, w0$o3])
-         +- Sort(orderBy=[b ASC, a ASC])
-            +- Exchange(distribution=[hash[b]])
-               +- Calc(select=[a, b])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, a DESC])
+         +- Exchange(distribution=[keep_input_as_is[hash[b]]])
+            +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[COUNT(a) AS w0$o0, $SUM0(a) AS w0$o1, MAX(a) AS w0$o2 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], window#1=[RANK(*) AS w0$o3 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, w0$o0, w0$o1, w0$o2, w0$o3])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[b ASC, a ASC])
+                     +- Exchange(distribution=[hash[b]])
+                        +- Calc(select=[a, b])
+                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -587,11 +623,14 @@ LogicalProject(EXPR$0=[RANK() OVER (PARTITION BY $1 ORDER BY $0 DESC NULLS LAST)
       <![CDATA[
 Calc(select=[w0$o0 AS $0, w1$o0 AS $1])
 +- OverAggregate(partitionBy=[b], orderBy=[a DESC], window#0=[RANK(*) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w1$o0])
-   +- Sort(orderBy=[b ASC, a DESC])
-      +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0])
-         +- Sort(orderBy=[b ASC, a ASC])
-            +- Exchange(distribution=[hash[b]])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, a DESC])
+         +- Exchange(distribution=[keep_input_as_is[hash[b]]])
+            +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[b ASC, a ASC])
+                     +- Exchange(distribution=[hash[b]])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -615,12 +654,15 @@ LogicalProject(EXPR$0=[CASE(>(COUNT($0) OVER (PARTITION BY $1 ORDER BY $0 NULLS
       <![CDATA[
 Calc(select=[CASE((w0$o0 > 0), w0$o1, null:INTEGER) AS EXPR$0, w1$o0 AS EXPR$1, w0$o2 AS EXPR$2])
 +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[COUNT(a) AS w1$o0, $SUM0(a) AS w0$o0, MAX(a) AS w0$o1 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, w0$o2, w1$o0, w0$o0, w0$o1])
-   +- Sort(orderBy=[b ASC, a ASC])
-      +- OverAggregate(partitionBy=[b], window#0=[MIN(a) AS w0$o2 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[a, b, w0$o2])
-         +- Sort(orderBy=[b ASC])
-            +- Exchange(distribution=[hash[b]])
-               +- Calc(select=[a, b])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, a ASC])
+         +- Exchange(distribution=[keep_input_as_is[hash[b]]])
+            +- OverAggregate(partitionBy=[b], window#0=[MIN(a) AS w0$o2 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[a, b, w0$o2])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[b ASC])
+                     +- Exchange(distribution=[hash[b]])
+                        +- Calc(select=[a, b])
+                           +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -643,10 +685,12 @@ LogicalProject(a=[$0], EXPR$1=[RANK() OVER (PARTITION BY $1 ORDER BY $2 NULLS FI
       <![CDATA[
 Calc(select=[a, w0$o0 AS $1, w1$o0 AS $2])
 +- OverAggregate(partitionBy=[b], orderBy=[c ASC, b ASC], window#0=[RANK(*) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0, w1$o0])
-   +- OverAggregate(partitionBy=[b], orderBy=[c ASC, a DESC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0])
-      +- Sort(orderBy=[b ASC, c ASC, a DESC])
-         +- Exchange(distribution=[hash[b]])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- OverAggregate(partitionBy=[b], orderBy=[c ASC, a DESC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, w0$o0])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[b ASC, c ASC, a DESC])
+               +- Exchange(distribution=[hash[b]])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/SortAggregateTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/SortAggregateTest.xml
index 4e9dfcd639b..0049f5705e3 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/SortAggregateTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/agg/SortAggregateTest.xml
@@ -30,10 +30,11 @@ LogicalAggregate(group=[{0}], EXPR$1=[var_sum($1)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[b], select=[b, var_sum(a) AS EXPR$1])
-+- Sort(orderBy=[b ASC])
-   +- Exchange(distribution=[hash[b]])
-      +- Calc(select=[b, a])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[b ASC])
+      +- Exchange(distribution=[hash[b]])
+         +- Calc(select=[b, a])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -51,10 +52,11 @@ LogicalAggregate(group=[{0}], EXPR$1=[var_sum($1)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[b], select=[b, var_sum(a) AS EXPR$1])
-+- Sort(orderBy=[b ASC])
-   +- Exchange(distribution=[hash[b]])
-      +- Calc(select=[b, a])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[b ASC])
+      +- Exchange(distribution=[hash[b]])
+         +- Calc(select=[b, a])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -72,10 +74,11 @@ LogicalAggregate(group=[{0}], EXPR$1=[var_sum($1)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[b], select=[b, var_sum(a) AS EXPR$1])
-+- Sort(orderBy=[b ASC])
-   +- Exchange(distribution=[hash[b]])
-      +- Calc(select=[b, a])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[b ASC])
+      +- Exchange(distribution=[hash[b]])
+         +- Calc(select=[b, a])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -220,12 +223,14 @@ LogicalAggregate(group=[{0, 1}])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[true], groupBy=[a, b], select=[a, b])
-+- Sort(orderBy=[a ASC, b ASC])
-   +- Exchange(distribution=[hash[a, b]])
-      +- LocalSortAggregate(groupBy=[a, b], select=[a, b])
-         +- Sort(orderBy=[a ASC, b ASC])
-            +- Calc(select=[a, b])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC, b ASC])
+      +- Exchange(distribution=[hash[a, b]])
+         +- LocalSortAggregate(groupBy=[a, b], select=[a, b])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC, b ASC])
+                  +- Calc(select=[a, b])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -243,10 +248,11 @@ LogicalAggregate(group=[{0, 1}])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[a, b], select=[a, b])
-+- Sort(orderBy=[a ASC, b ASC])
-   +- Exchange(distribution=[hash[a, b]])
-      +- Calc(select=[a, b])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC, b ASC])
+      +- Exchange(distribution=[hash[a, b]])
+         +- Calc(select=[a, b])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -264,12 +270,14 @@ LogicalAggregate(group=[{0, 1}])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[true], groupBy=[a, b], select=[a, b])
-+- Sort(orderBy=[a ASC, b ASC])
-   +- Exchange(distribution=[hash[a, b]])
-      +- LocalSortAggregate(groupBy=[a, b], select=[a, b])
-         +- Sort(orderBy=[a ASC, b ASC])
-            +- Calc(select=[a, b])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC, b ASC])
+      +- Exchange(distribution=[hash[a, b]])
+         +- LocalSortAggregate(groupBy=[a, b], select=[a, b])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC, b ASC])
+                  +- Calc(select=[a, b])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -645,11 +653,13 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($1)], EXPR$2=[COUNT($2)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS EXPR$1, Final_COUNT(count$1) AS EXPR$2])
-+- Sort(orderBy=[a ASC])
-   +- Exchange(distribution=[hash[a]])
-      +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
-         +- Sort(orderBy=[a ASC])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC])
+      +- Exchange(distribution=[hash[a]])
+         +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -790,9 +800,10 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($1)], EXPR$2=[COUNT($2)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[a], select=[a, SUM(b) AS EXPR$1, COUNT(c) AS EXPR$2])
-+- Sort(orderBy=[a ASC])
-   +- Exchange(distribution=[hash[a]])
-      +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC])
+      +- Exchange(distribution=[hash[a]])
+         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -809,11 +820,13 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($1)], EXPR$2=[COUNT($2)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS EXPR$1, Final_COUNT(count$1) AS EXPR$2])
-+- Sort(orderBy=[a ASC])
-   +- Exchange(distribution=[hash[a]])
-      +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
-         +- Sort(orderBy=[a ASC])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC])
+      +- Exchange(distribution=[hash[a]])
+         +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -831,12 +844,14 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($1)], EXPR$2=[COUNT($2)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS EXPR$1, Final_COUNT(count$1) AS EXPR$2])
-+- Sort(orderBy=[a ASC])
-   +- Exchange(distribution=[hash[a]])
-      +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
-         +- Sort(orderBy=[a ASC])
-            +- Calc(select=[a, b, c], where=[(a = 1)])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC])
+      +- Exchange(distribution=[hash[a]])
+         +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC])
+                  +- Calc(select=[a, b, c], where=[(a = 1)])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -854,10 +869,11 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($1)], EXPR$2=[COUNT($2)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[a], select=[a, SUM(b) AS EXPR$1, COUNT(c) AS EXPR$2])
-+- Sort(orderBy=[a ASC])
-   +- Exchange(distribution=[hash[a]])
-      +- Calc(select=[a, b, c], where=[(a = 1)])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC])
+      +- Exchange(distribution=[hash[a]])
+         +- Calc(select=[a, b, c], where=[(a = 1)])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -875,12 +891,14 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($1)], EXPR$2=[COUNT($2)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_SUM(sum$0) AS EXPR$1, Final_COUNT(count$1) AS EXPR$2])
-+- Sort(orderBy=[a ASC])
-   +- Exchange(distribution=[hash[a]])
-      +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
-         +- Sort(orderBy=[a ASC])
-            +- Calc(select=[a, b, c], where=[(a = 1)])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC])
+      +- Exchange(distribution=[hash[a]])
+         +- LocalSortAggregate(groupBy=[a], select=[a, Partial_SUM(b) AS sum$0, Partial_COUNT(c) AS count$1])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC])
+                  +- Calc(select=[a, b, c], where=[(a = 1)])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -902,12 +920,14 @@ LogicalProject(a=[$0], EXPR$1=[$2], c=[$1])
       <![CDATA[
 Calc(select=[a, EXPR$1, 'test' AS c])
 +- SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_MAX(max$0) AS EXPR$1])
-   +- Sort(orderBy=[a ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- LocalSortAggregate(groupBy=[a], select=[a, Partial_MAX(b) AS max$0])
-            +- Sort(orderBy=[a ASC])
-               +- Calc(select=[a, b])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- LocalSortAggregate(groupBy=[a], select=[a, Partial_MAX(b) AS max$0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[a ASC])
+                     +- Calc(select=[a, b])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -929,10 +949,11 @@ LogicalProject(a=[$0], EXPR$1=[$2], c=[$1])
       <![CDATA[
 Calc(select=[a, EXPR$1, 'test' AS c])
 +- SortAggregate(isMerge=[false], groupBy=[a], select=[a, MAX(b) AS EXPR$1])
-   +- Sort(orderBy=[a ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- Calc(select=[a, b])
-            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- Calc(select=[a, b])
+               +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -954,12 +975,14 @@ LogicalProject(a=[$0], EXPR$1=[$2], c=[$1])
       <![CDATA[
 Calc(select=[a, EXPR$1, 'test' AS c])
 +- SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_MAX(max$0) AS EXPR$1])
-   +- Sort(orderBy=[a ASC])
-      +- Exchange(distribution=[hash[a]])
-         +- LocalSortAggregate(groupBy=[a], select=[a, Partial_MAX(b) AS max$0])
-            +- Sort(orderBy=[a ASC])
-               +- Calc(select=[a, b])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[a ASC])
+         +- Exchange(distribution=[hash[a]])
+            +- LocalSortAggregate(groupBy=[a], select=[a, Partial_MAX(b) AS max$0])
+               +- Exchange(distribution=[forward])
+                  +- Sort(orderBy=[a ASC])
+                     +- Calc(select=[a, b])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -1340,10 +1363,11 @@ LogicalAggregate(group=[{0}], EXPR$1=[var_sum($1)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[b], select=[b, var_sum(a) AS EXPR$1])
-+- Sort(orderBy=[b ASC])
-   +- Exchange(distribution=[hash[b]])
-      +- Calc(select=[b, a])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[b ASC])
+      +- Exchange(distribution=[hash[b]])
+         +- Calc(select=[b, a])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -1361,10 +1385,11 @@ LogicalAggregate(group=[{0}], EXPR$1=[var_sum($1)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[b], select=[b, var_sum(a) AS EXPR$1])
-+- Sort(orderBy=[b ASC])
-   +- Exchange(distribution=[hash[b]])
-      +- Calc(select=[b, a])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[b ASC])
+      +- Exchange(distribution=[hash[b]])
+         +- Calc(select=[b, a])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
@@ -1412,10 +1437,11 @@ LogicalAggregate(group=[{0}], EXPR$1=[var_sum($1)])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortAggregate(isMerge=[false], groupBy=[b], select=[b, var_sum(a) AS EXPR$1])
-+- Sort(orderBy=[b ASC])
-   +- Exchange(distribution=[hash[b]])
-      +- Calc(select=[b, a])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[b ASC])
+      +- Exchange(distribution=[hash[b]])
+         +- Calc(select=[b, a])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable1, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/BroadcastHashSemiAntiJoinTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/BroadcastHashSemiAntiJoinTest.xml
index 4c80c5ee11c..cfa824ce8ad 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/BroadcastHashSemiAntiJoinTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/BroadcastHashSemiAntiJoinTest.xml
@@ -736,10 +736,11 @@ HashJoin(joinType=[LeftSemiJoin], where=[((b = rk) AND (a <> d))], select=[a, b,
 +- Exchange(distribution=[broadcast])
    +- Calc(select=[w0$o0 AS rk, d])
       +- OverAggregate(partitionBy=[d], orderBy=[e ASC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[d, e, w0$o0])
-         +- Sort(orderBy=[d ASC, e ASC])
-            +- Exchange(distribution=[hash[d]])
-               +- Calc(select=[d, e])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[d ASC, e ASC])
+               +- Exchange(distribution=[hash[d]])
+                  +- Calc(select=[d, e])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -1167,11 +1168,12 @@ HashJoin(joinType=[LeftSemiJoin], where=[((a = $0) AND (b = $1))], select=[a, b,
 +- Exchange(distribution=[broadcast])
    +- Calc(select=[w0$o0 AS $0, w1$o0 AS $1])
       +- OverAggregate(partitionBy=[f], orderBy=[d ASC], window#0=[MIN(e) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[d, e, f, w0$o0, w1$o0])
-         +- Sort(orderBy=[f ASC, d ASC])
-            +- Exchange(distribution=[hash[f]])
-               +- OverAggregate(window#0=[MAX(d) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[d, e, f, w0$o0])
-                  +- Exchange(distribution=[single])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[f ASC, d ASC])
+               +- Exchange(distribution=[hash[f]])
+                  +- OverAggregate(window#0=[MAX(d) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[d, e, f, w0$o0])
+                     +- Exchange(distribution=[single])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/LookupJoinTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/LookupJoinTest.xml
index ba8ae14ce5f..004c4249c7d 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/LookupJoinTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/LookupJoinTest.xml
@@ -587,7 +587,7 @@ Calc(select=[EXPR$0, EXPR$1, EXPR$2])
    +- Exchange(distribution=[hash[b, b0]])
       +- LocalHashAggregate(groupBy=[b, b0], select=[b, b0, Partial_COUNT(a) AS count$0, Partial_COUNT(id) AS count$1, Partial_SUM(a0) AS sum$2])
          +- HashJoin(joinType=[InnerJoin], where=[(a = a0)], select=[b, a, id, a0, b0], build=[right])
-            :- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
+            :- Exchange(distribution=[hash[a]])
             :  +- LookupJoin(table=[default_catalog.default_database.LookupTable], joinType=[InnerJoin], lookup=[id=a], where=[(age > 10)], select=[b, a, id])(reuse_id=[1])
             :     +- Calc(select=[b, a])
             :        +- HashAggregate(isMerge=[true], groupBy=[a, b], select=[a, b])
@@ -663,7 +663,7 @@ Calc(select=[EXPR$0, EXPR$1, EXPR$2])
    +- Exchange(distribution=[hash[b, b0]])
       +- LocalHashAggregate(groupBy=[b, b0], select=[b, b0, Partial_COUNT(a) AS count$0, Partial_COUNT(id) AS count$1, Partial_SUM(a0) AS sum$2])
          +- HashJoin(joinType=[InnerJoin], where=[(a = a0)], select=[b, a, id, a0, b0], build=[right])
-            :- Exchange(distribution=[hash[a]], shuffle_mode=[BATCH])
+            :- Exchange(distribution=[hash[a]])
             :  +- LookupJoin(table=[default_catalog.default_database.LookupTable], joinType=[InnerJoin], lookup=[id=a], where=[(age > 10)], select=[b, a, id])(reuse_id=[1])
             :     +- Calc(select=[b, a])
             :        +- HashAggregate(isMerge=[true], groupBy=[a, b], select=[a, b])
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/NestedLoopSemiAntiJoinTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/NestedLoopSemiAntiJoinTest.xml
index 8ca8a79c874..4da50b5dc3b 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/NestedLoopSemiAntiJoinTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/NestedLoopSemiAntiJoinTest.xml
@@ -918,10 +918,11 @@ NestedLoopJoin(joinType=[LeftSemiJoin], where=[((b = rk) AND (a <> d))], select=
 +- Exchange(distribution=[broadcast])
    +- Calc(select=[w0$o0 AS rk, d])
       +- OverAggregate(partitionBy=[d], orderBy=[e ASC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[d, e, w0$o0])
-         +- Sort(orderBy=[d ASC, e ASC])
-            +- Exchange(distribution=[hash[d]])
-               +- Calc(select=[d, e])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[d ASC, e ASC])
+               +- Exchange(distribution=[hash[d]])
+                  +- Calc(select=[d, e])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -1432,11 +1433,12 @@ NestedLoopJoin(joinType=[LeftSemiJoin], where=[((a = $0) AND (b = $1))], select=
 +- Exchange(distribution=[broadcast])
    +- Calc(select=[w0$o0 AS $0, w1$o0 AS $1])
       +- OverAggregate(partitionBy=[f], orderBy=[d ASC], window#0=[MIN(e) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[d, e, f, w0$o0, w1$o0])
-         +- Sort(orderBy=[f ASC, d ASC])
-            +- Exchange(distribution=[hash[f]])
-               +- OverAggregate(window#0=[MAX(d) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[d, e, f, w0$o0])
-                  +- Exchange(distribution=[single])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[f ASC, d ASC])
+               +- Exchange(distribution=[hash[f]])
+                  +- OverAggregate(window#0=[MAX(d) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[d, e, f, w0$o0])
+                     +- Exchange(distribution=[single])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SemiAntiJoinTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SemiAntiJoinTest.xml
index 88acd77e0fb..1c58e05ea77 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SemiAntiJoinTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SemiAntiJoinTest.xml
@@ -951,10 +951,11 @@ HashJoin(joinType=[LeftSemiJoin], where=[((b = rk) AND (a <> d))], select=[a, b,
 +- Exchange(distribution=[hash[rk]])
    +- Calc(select=[w0$o0 AS rk, d])
       +- OverAggregate(partitionBy=[d], orderBy=[e ASC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[d, e, w0$o0])
-         +- Sort(orderBy=[d ASC, e ASC])
-            +- Exchange(distribution=[hash[d]])
-               +- Calc(select=[d, e])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[d ASC, e ASC])
+               +- Exchange(distribution=[hash[d]])
+                  +- Calc(select=[d, e])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -1486,11 +1487,12 @@ HashJoin(joinType=[LeftSemiJoin], where=[((a = $0) AND (b = $1))], select=[a, b,
 +- Exchange(distribution=[hash[$0, $1]])
    +- Calc(select=[w0$o0 AS $0, w1$o0 AS $1])
       +- OverAggregate(partitionBy=[f], orderBy=[d ASC], window#0=[MIN(e) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[d, e, f, w0$o0, w1$o0])
-         +- Sort(orderBy=[f ASC, d ASC])
-            +- Exchange(distribution=[hash[f]])
-               +- OverAggregate(window#0=[MAX(d) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[d, e, f, w0$o0])
-                  +- Exchange(distribution=[single])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[f ASC, d ASC])
+               +- Exchange(distribution=[hash[f]])
+                  +- OverAggregate(window#0=[MAX(d) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[d, e, f, w0$o0])
+                     +- Exchange(distribution=[single])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/ShuffledHashSemiAntiJoinTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/ShuffledHashSemiAntiJoinTest.xml
index 8e7e1523cf3..03d58c2ae56 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/ShuffledHashSemiAntiJoinTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/ShuffledHashSemiAntiJoinTest.xml
@@ -801,10 +801,11 @@ HashJoin(joinType=[LeftSemiJoin], where=[((b = rk) AND (a <> d))], select=[a, b,
 +- Exchange(distribution=[hash[rk]])
    +- Calc(select=[w0$o0 AS rk, d])
       +- OverAggregate(partitionBy=[d], orderBy=[e ASC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[d, e, w0$o0])
-         +- Sort(orderBy=[d ASC, e ASC])
-            +- Exchange(distribution=[hash[d]])
-               +- Calc(select=[d, e])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[d ASC, e ASC])
+               +- Exchange(distribution=[hash[d]])
+                  +- Calc(select=[d, e])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -1289,11 +1290,12 @@ HashJoin(joinType=[LeftSemiJoin], where=[((a = $0) AND (b = $1))], select=[a, b,
 +- Exchange(distribution=[hash[$0, $1]])
    +- Calc(select=[w0$o0 AS $0, w1$o0 AS $1])
       +- OverAggregate(partitionBy=[f], orderBy=[d ASC], window#0=[MIN(e) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[d, e, f, w0$o0, w1$o0])
-         +- Sort(orderBy=[f ASC, d ASC])
-            +- Exchange(distribution=[hash[f]])
-               +- OverAggregate(window#0=[MAX(d) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[d, e, f, w0$o0])
-                  +- Exchange(distribution=[single])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[f ASC, d ASC])
+               +- Exchange(distribution=[hash[f]])
+                  +- OverAggregate(window#0=[MAX(d) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[d, e, f, w0$o0])
+                     +- Exchange(distribution=[single])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SingleRowJoinTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SingleRowJoinTest.xml
index 3b25e781751..e319e8209ef 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SingleRowJoinTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SingleRowJoinTest.xml
@@ -237,20 +237,18 @@ LogicalProject(EXPR$0=[*($0, 0.1:DECIMAL(2, 1))])
     <Resource name="optimized exec plan">
       <![CDATA[
 Calc(select=[a2, EXPR$1])
-+- NestedLoopJoin(joinType=[InnerJoin], where=[(EXPR$1 > $f0)], select=[a2, EXPR$1, $f0], build=[right], singleRowJoin=[true])
-   :- Exchange(distribution=[any])
-   :  +- HashAggregate(isMerge=[true], groupBy=[a2], select=[a2, Final_SUM(sum$0) AS EXPR$1])
-   :     +- Exchange(distribution=[hash[a2]])
-   :        +- LocalHashAggregate(groupBy=[a2], select=[a2, Partial_SUM(a1) AS sum$0])
-   :           +- LegacyTableSourceScan(table=[[default_catalog, default_database, A, source: [TestTableSource(a1, a2)]]], fields=[a1, a2])(reuse_id=[1])
-   +- Exchange(distribution=[broadcast])
-      +- HashAggregate(isMerge=[false], select=[SINGLE_VALUE(EXPR$0) AS $f0])
-         +- Calc(select=[($f0 * 0.1) AS EXPR$0])
-            +- HashAggregate(isMerge=[true], select=[Final_SUM(sum$0) AS $f0])
-               +- Exchange(distribution=[single])
-                  +- LocalHashAggregate(select=[Partial_SUM(a1) AS sum$0])
-                     +- Calc(select=[a1])
-                        +- Reused(reference_id=[1])
++- MultipleInput(readOrder=[0,1], members=[\nNestedLoopJoin(joinType=[InnerJoin], where=[(EXPR$1 > $f0)], select=[a2, EXPR$1, $f0], build=[right], singleRowJoin=[true])\n:- HashAggregate(isMerge=[true], groupBy=[a2], select=[a2, Final_SUM(sum$0) AS EXPR$1])\n:  +- [#2] Exchange(distribution=[hash[a2]])\n+- [#1] Exchange(distribution=[broadcast])\n])
+   :- Exchange(distribution=[broadcast])
+   :  +- HashAggregate(isMerge=[false], select=[SINGLE_VALUE(EXPR$0) AS $f0])
+   :     +- Calc(select=[($f0 * 0.1) AS EXPR$0])
+   :        +- HashAggregate(isMerge=[true], select=[Final_SUM(sum$0) AS $f0])
+   :           +- Exchange(distribution=[single])
+   :              +- LocalHashAggregate(select=[Partial_SUM(a1) AS sum$0])
+   :                 +- Calc(select=[a1])
+   :                    +- LegacyTableSourceScan(table=[[default_catalog, default_database, A, source: [TestTableSource(a1, a2)]]], fields=[a1, a2])(reuse_id=[1])
+   +- Exchange(distribution=[hash[a2]])
+      +- LocalHashAggregate(groupBy=[a2], select=[a2, Partial_SUM(a1) AS sum$0])
+         +- Reused(reference_id=[1])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SortMergeSemiAntiJoinTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SortMergeSemiAntiJoinTest.xml
index 2097b1c715d..fb6256f6e6a 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SortMergeSemiAntiJoinTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/sql/join/SortMergeSemiAntiJoinTest.xml
@@ -801,10 +801,11 @@ SortMergeJoin(joinType=[LeftSemiJoin], where=[((b = rk) AND (a <> d))], select=[
 +- Exchange(distribution=[hash[rk]])
    +- Calc(select=[w0$o0 AS rk, d])
       +- OverAggregate(partitionBy=[d], orderBy=[e ASC], window#0=[RANK(*) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[d, e, w0$o0])
-         +- Sort(orderBy=[d ASC, e ASC])
-            +- Exchange(distribution=[hash[d]])
-               +- Calc(select=[d, e])
-                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[d ASC, e ASC])
+               +- Exchange(distribution=[hash[d]])
+                  +- Calc(select=[d, e])
+                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -1289,11 +1290,12 @@ SortMergeJoin(joinType=[LeftSemiJoin], where=[((a = $0) AND (b = $1))], select=[
 +- Exchange(distribution=[hash[$0, $1]])
    +- Calc(select=[w0$o0 AS $0, w1$o0 AS $1])
       +- OverAggregate(partitionBy=[f], orderBy=[d ASC], window#0=[MIN(e) AS w1$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[d, e, f, w0$o0, w1$o0])
-         +- Sort(orderBy=[f ASC, d ASC])
-            +- Exchange(distribution=[hash[f]])
-               +- OverAggregate(window#0=[MAX(d) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[d, e, f, w0$o0])
-                  +- Exchange(distribution=[single])
-                     +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
+         +- Exchange(distribution=[forward])
+            +- Sort(orderBy=[f ASC, d ASC])
+               +- Exchange(distribution=[hash[f]])
+                  +- OverAggregate(window#0=[MAX(d) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING], select=[d, e, f, w0$o0])
+                     +- Exchange(distribution=[single])
+                        +- LegacyTableSourceScan(table=[[default_catalog, default_database, r, source: [TestTableSource(d, e, f)]]], fields=[d, e, f])
 ]]>
     </Resource>
   </TestCase>
@@ -1976,29 +1978,26 @@ Calc(select=[b])
 +- SortMergeJoin(joinType=[LeftAntiJoin], where=[((d IS NULL OR ($f3 = d)) AND (c = f))], select=[b, c, $f3])
    :- Exchange(distribution=[hash[c]])
    :  +- Calc(select=[b, c, CASE(((c0 = 0) OR (i0 IS NULL AND (ck >= c0) AND a IS NOT NULL)), 1, ((c1 = 0) OR (i IS NULL AND (ck0 >= c1) AND a IS NOT NULL)), 2, 3) AS $f3])
-   :     +- MultipleInput(readOrder=[1,0,0], members=[\nSortMergeJoin(joinType=[LeftOuterJoin], where=[(a = EXPR$0)], select=[a, b, c, c0, ck, i0, c1, ck0, EXPR$0, i])\n:- NestedLoopJoin(joinType=[InnerJoin], where=[true], select=[a, b, c, c0, ck, i0, c1, ck0], build=[right], singleRowJoin=[true])\n:  :- [#1] Exchange(distribution=[any])\n:  +- [#2] Exchange(distribution=[broadcast])\n+- Calc(select=[EXPR$0, true AS i])\n   +- HashAggregate(isMerge=[true], groupBy=[EXPR$0], select=[EXPR$ [...]
-   :        :- Exchange(distribution=[any])
-   :        :  +- Calc(select=[a, b, c, c0, ck, i0])
-   :        :     +- MultipleInput(readOrder=[1,0,0], members=[\nSortMergeJoin(joinType=[LeftOuterJoin], where=[(a = i)], select=[a, b, c, c0, ck, i, i0])\n:- NestedLoopJoin(joinType=[InnerJoin], where=[true], select=[a, b, c, c0, ck], build=[right], singleRowJoin=[true])\n:  :- [#1] Exchange(distribution=[hash[a]])\n:  +- [#2] Exchange(distribution=[broadcast])\n+- Calc(select=[i, true AS i0])\n   +- HashAggregate(isMerge=[true], groupBy=[i], select=[i])\n      +- [#3] Exchange(distribu [...]
-   :        :        :- Exchange(distribution=[hash[a]])
-   :        :        :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, l, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
-   :        :        :- Exchange(distribution=[broadcast])
-   :        :        :  +- HashAggregate(isMerge=[true], select=[Final_COUNT(count1$0) AS c, Final_COUNT(count$1) AS ck])
-   :        :        :     +- Exchange(distribution=[single])
-   :        :        :        +- LocalHashAggregate(select=[Partial_COUNT(*) AS count1$0, Partial_COUNT(i) AS count$1])
-   :        :        :           +- Calc(select=[i])(reuse_id=[1])
-   :        :        :              +- LegacyTableSourceScan(table=[[default_catalog, default_database, t, source: [TestTableSource(i, j, k)]]], fields=[i, j, k])(reuse_id=[2])
-   :        :        +- Exchange(distribution=[hash[i]])
-   :        :           +- LocalHashAggregate(groupBy=[i], select=[i])
-   :        :              +- Reused(reference_id=[1])
+   :     +- MultipleInput(readOrder=[0,0,1,0,1], members=[\nSortMergeJoin(joinType=[LeftOuterJoin], where=[(a = EXPR$0)], select=[a, b, c, c0, ck, i0, c1, ck0, EXPR$0, i])\n:- NestedLoopJoin(joinType=[InnerJoin], where=[true], select=[a, b, c, c0, ck, i0, c1, ck0], build=[right], singleRowJoin=[true])\n:  :- Calc(select=[a, b, c, c0, ck, i0])\n:  :  +- SortMergeJoin(joinType=[LeftOuterJoin], where=[(a = i)], select=[a, b, c, c0, ck, i, i0])\n:  :     :- NestedLoopJoin(joinType=[InnerJoin [...]
    :        :- Exchange(distribution=[broadcast])
    :        :  +- HashAggregate(isMerge=[true], select=[Final_COUNT(count1$0) AS c, Final_COUNT(count$1) AS ck])
    :        :     +- Exchange(distribution=[single])
    :        :        +- LocalHashAggregate(select=[Partial_COUNT(*) AS count1$0, Partial_COUNT(EXPR$0) AS count$1])
-   :        :           +- Calc(select=[CAST(j AS INTEGER) AS EXPR$0])(reuse_id=[3])
+   :        :           +- Calc(select=[CAST(j AS INTEGER) AS EXPR$0])(reuse_id=[1])
+   :        :              +- LegacyTableSourceScan(table=[[default_catalog, default_database, t, source: [TestTableSource(i, j, k)]]], fields=[i, j, k])(reuse_id=[2])
+   :        :- Exchange(distribution=[hash[EXPR$0]])
+   :        :  +- LocalHashAggregate(groupBy=[EXPR$0], select=[EXPR$0])
+   :        :     +- Reused(reference_id=[1])
+   :        :- Exchange(distribution=[hash[a]])
+   :        :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, l, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
+   :        :- Exchange(distribution=[broadcast])
+   :        :  +- HashAggregate(isMerge=[true], select=[Final_COUNT(count1$0) AS c, Final_COUNT(count$1) AS ck])
+   :        :     +- Exchange(distribution=[single])
+   :        :        +- LocalHashAggregate(select=[Partial_COUNT(*) AS count1$0, Partial_COUNT(i) AS count$1])
+   :        :           +- Calc(select=[i])(reuse_id=[3])
    :        :              +- Reused(reference_id=[2])
-   :        +- Exchange(distribution=[hash[EXPR$0]])
-   :           +- LocalHashAggregate(groupBy=[EXPR$0], select=[EXPR$0])
+   :        +- Exchange(distribution=[hash[i]])
+   :           +- LocalHashAggregate(groupBy=[i], select=[i])
    :              +- Reused(reference_id=[3])
    +- Exchange(distribution=[hash[f]])
       +- Calc(select=[d, f])
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/GroupWindowTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/GroupWindowTest.xml
index c18ae5314ba..5326122dc42 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/GroupWindowTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/GroupWindowTest.xml
@@ -96,12 +96,13 @@ LogicalProject(string=[$0], EXPR$0=[$1])
     <Resource name="optimized exec plan">
       <![CDATA[
 SortWindowAggregate(groupBy=[string], window=[TumblingGroupWindow('w, long, 5)], select=[string, Final_*org.apache.flink.table.planner.plan.utils.JavaUserDefinedAggFunctions$WeightedAvgWithMerge*(EXPR$0) AS EXPR$0])
-+- Sort(orderBy=[string ASC, assignedWindow$ ASC])
-   +- Exchange(distribution=[hash[string]])
-      +- LocalSortWindowAggregate(groupBy=[string], window=[TumblingGroupWindow('w, long, 5)], select=[string, Partial_*org.apache.flink.table.planner.plan.utils.JavaUserDefinedAggFunctions$WeightedAvgWithMerge*(long, int0) AS EXPR$0])
-         +- Calc(select=[long, int, string, CAST(int AS BIGINT) AS int0])
-            +- Sort(orderBy=[string ASC, long ASC])
-               +- LegacyTableSourceScan(table=[[default_catalog, default_database, Table1, source: [TestTableSource(long, int, string)]]], fields=[long, int, string])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[string ASC, assignedWindow$ ASC])
+      +- Exchange(distribution=[hash[string]])
+         +- LocalSortWindowAggregate(groupBy=[string], window=[TumblingGroupWindow('w, long, 5)], select=[string, Partial_*org.apache.flink.table.planner.plan.utils.JavaUserDefinedAggFunctions$WeightedAvgWithMerge*(long, int0) AS EXPR$0])
+            +- Calc(select=[long, int, string, CAST(int AS BIGINT) AS int0])
+               +- Sort(orderBy=[string ASC, long ASC])
+                  +- LegacyTableSourceScan(table=[[default_catalog, default_database, Table1, source: [TestTableSource(long, int, string)]]], fields=[long, int, string])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonAggregateTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonAggregateTest.xml
index 1e834fddc15..d5f86303177 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonAggregateTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonAggregateTest.xml
@@ -27,9 +27,10 @@ LogicalProject(b=[$0], EXPR$0=[$1])
     <Resource name="optimized exec plan">
       <![CDATA[
 PythonGroupAggregate(groupBy=[b], select=[b, PandasAggregateFunction(a, c) AS EXPR$0])
-+- Sort(orderBy=[b ASC])
-   +- Exchange(distribution=[hash[b]])
-      +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
++- Exchange(distribution=[keep_input_as_is[hash[b]]])
+   +- Sort(orderBy=[b ASC])
+      +- Exchange(distribution=[hash[b]])
+         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonGroupWindowAggregateTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonGroupWindowAggregateTest.xml
index a8e2e326bad..0b4c66833ee 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonGroupWindowAggregateTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonGroupWindowAggregateTest.xml
@@ -28,9 +28,10 @@ LogicalProject(b=[$0], EXPR$0=[$2], EXPR$1=[$3], EXPR$2=[$1])
       <![CDATA[
 Calc(select=[b, EXPR$0, EXPR$1, EXPR$2])
 +- PythonGroupWindowAggregate(groupBy=[b], window=[TumblingGroupWindow('w, rowtime, 5)], properties=[EXPR$0, EXPR$1], select=[b, PandasAggregateFunction(a, c) AS EXPR$2])
-   +- Sort(orderBy=[b ASC, rowtime ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, rowtime)]]], fields=[a, b, c, rowtime])
+   +- Exchange(distribution=[keep_input_as_is[hash[b]]])
+      +- Sort(orderBy=[b ASC, rowtime ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, rowtime)]]], fields=[a, b, c, rowtime])
 ]]>
     </Resource>
   </TestCase>
@@ -46,9 +47,10 @@ LogicalProject(b=[$0], EXPR$0=[$2], EXPR$1=[$3], EXPR$2=[$1])
       <![CDATA[
 Calc(select=[b, EXPR$0, EXPR$1, EXPR$2])
 +- PythonGroupWindowAggregate(groupBy=[b], window=[SlidingGroupWindow('w, rowtime, 5, 2)], properties=[EXPR$0, EXPR$1], select=[b, PandasAggregateFunction(a, c) AS EXPR$2])
-   +- Sort(orderBy=[b ASC, rowtime ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, rowtime)]]], fields=[a, b, c, rowtime])
+   +- Exchange(distribution=[keep_input_as_is[hash[b]]])
+      +- Sort(orderBy=[b ASC, rowtime ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, rowtime)]]], fields=[a, b, c, rowtime])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonOverWindowAggregateTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonOverWindowAggregateTest.xml
index c1d3e4af8ed..191c5a555fa 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonOverWindowAggregateTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/PythonOverWindowAggregateTest.xml
@@ -27,9 +27,10 @@ LogicalProject(b=[$1], _c1=[AS(*org.apache.flink.table.planner.runtime.utils.Jav
       <![CDATA[
 Calc(select=[b, w0$o0 AS _c1])
 +- PythonOverAggregate(partitionBy=[b], orderBy=[rowtime ASC], window#0=[PandasAggregateFunction(a, c) AS w0$o0 RANG BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, c, rowtime, w0$o0])
-   +- Sort(orderBy=[b ASC, rowtime ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, rowtime)]]], fields=[a, b, c, rowtime])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, rowtime ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, rowtime)]]], fields=[a, b, c, rowtime])
 ]]>
     </Resource>
   </TestCase>
@@ -44,9 +45,10 @@ LogicalProject(b=[$1], _c1=[AS(*org.apache.flink.table.planner.runtime.utils.Jav
       <![CDATA[
 Calc(select=[b, w0$o0 AS _c1])
 +- PythonOverAggregate(partitionBy=[b], orderBy=[rowtime ASC], window#0=[PandasAggregateFunction(a, c) AS w0$o0 ROWS BETWEEN 10 PRECEDING AND CURRENT ROW], select=[a, b, c, rowtime, w0$o0])
-   +- Sort(orderBy=[b ASC, rowtime ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, rowtime)]]], fields=[a, b, c, rowtime])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, rowtime ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- LegacyTableSourceScan(table=[[default_catalog, default_database, MyTable, source: [TestTableSource(a, b, c, rowtime)]]], fields=[a, b, c, rowtime])
 ]]>
     </Resource>
   </TestCase>
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/SetOperatorsTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/SetOperatorsTest.xml
index 7f0ef81e18f..7d800a1411d 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/SetOperatorsTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/batch/table/SetOperatorsTest.xml
@@ -87,7 +87,7 @@ LogicalProject(a1=[AS($0, _UTF-16LE'a1')])
     <Resource name="optimized exec plan">
       <![CDATA[
 HashJoin(joinType=[LeftSemiJoin], where=[(c = a1)], select=[a, b, c], build=[right], tryDistinctBuildRow=[true])
-:- Exchange(distribution=[hash[c]], shuffle_mode=[BATCH])
+:- Exchange(distribution=[hash[c]])
 :  +- LegacyTableSourceScan(table=[[default_catalog, default_database, A, source: [TestTableSource(a, b, c)]]], fields=[a, b, c])(reuse_id=[1])
 +- Exchange(distribution=[hash[a1]])
    +- LocalHashAggregate(groupBy=[a1], select=[a1])
diff --git a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/nodes/exec/operator/BatchOperatorNameTest.xml b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/nodes/exec/operator/BatchOperatorNameTest.xml
index 2b3a0c1a854..d9f69879d16 100644
--- a/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/nodes/exec/operator/BatchOperatorNameTest.xml
+++ b/flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/nodes/exec/operator/BatchOperatorNameTest.xml
@@ -1338,9 +1338,10 @@ Calc(select=[b, w0$o0 AS $1])
 == Optimized Execution Plan ==
 Calc(select=[b, w0$o0 AS $1])
 +- OverAggregate(partitionBy=[b], orderBy=[rowtime ASC], window#0=[COUNT(a) AS w0$o0 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW], select=[a, b, rowtime, w0$o0])
-   +- Sort(orderBy=[b ASC, rowtime ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b, rowtime], metadata=[]]], fields=[a, b, rowtime])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, rowtime ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b, rowtime], metadata=[]]], fields=[a, b, rowtime])
 
 == Physical Execution Plan ==
 {
@@ -1403,9 +1404,10 @@ Calc(select=[b, w0$o0 AS $1])
 == Optimized Execution Plan ==
 Calc(select=[b, w0$o0 AS $1])
 +- OverAggregate(partitionBy=[b], orderBy=[rowtime ASC], window#0=[COUNT(a) AS w0$o0 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW], select=[a, b, rowtime, w0$o0])
-   +- Sort(orderBy=[b ASC, rowtime ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b, rowtime], metadata=[]]], fields=[a, b, rowtime])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, rowtime ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b, rowtime], metadata=[]]], fields=[a, b, rowtime])
 
 == Physical Execution Plan ==
 {
@@ -1470,9 +1472,10 @@ Calc(select=[a, w0$o0], where=[<=(w0$o0, a)])
 == Optimized Execution Plan ==
 Calc(select=[a, w0$o0], where=[(w0$o0 <= a)])
 +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[ROW_NUMBER(*) AS w0$o0 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, w0$o0])
-   +- Sort(orderBy=[b ASC, a ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b], metadata=[]]], fields=[a, b])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, a ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b], metadata=[]]], fields=[a, b])
 
 == Physical Execution Plan ==
 {
@@ -1537,9 +1540,10 @@ Calc(select=[a, w0$o0], where=[<=(w0$o0, a)])
 == Optimized Execution Plan ==
 Calc(select=[a, w0$o0], where=[(w0$o0 <= a)])
 +- OverAggregate(partitionBy=[b], orderBy=[a ASC], window#0=[ROW_NUMBER(*) AS w0$o0 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], select=[a, b, w0$o0])
-   +- Sort(orderBy=[b ASC, a ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b], metadata=[]]], fields=[a, b])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, a ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b], metadata=[]]], fields=[a, b])
 
 == Physical Execution Plan ==
 {
@@ -1608,16 +1612,20 @@ SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_COUNT(count$0) AS b]
 
 == Optimized Execution Plan ==
 SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_COUNT(count$0) AS b])
-+- Sort(orderBy=[a ASC])
-   +- Exchange(distribution=[hash[a]])
-      +- LocalSortAggregate(groupBy=[a], select=[a, Partial_COUNT(b) AS count$0])
-         +- Sort(orderBy=[a ASC])
-            +- SortAggregate(isMerge=[true], groupBy=[a, b], select=[a, b])
-               +- Sort(orderBy=[a ASC, b ASC])
-                  +- Exchange(distribution=[hash[a, b]])
-                     +- LocalSortAggregate(groupBy=[a, b], select=[a, b])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC])
+      +- Exchange(distribution=[hash[a]])
+         +- LocalSortAggregate(groupBy=[a], select=[a, Partial_COUNT(b) AS count$0])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC])
+                  +- SortAggregate(isMerge=[true], groupBy=[a, b], select=[a, b])
+                     +- Exchange(distribution=[forward])
                         +- Sort(orderBy=[a ASC, b ASC])
-                           +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b], metadata=[]]], fields=[a, b])
+                           +- Exchange(distribution=[hash[a, b]])
+                              +- LocalSortAggregate(groupBy=[a, b], select=[a, b])
+                                 +- Exchange(distribution=[forward])
+                                    +- Sort(orderBy=[a ASC, b ASC])
+                                       +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b], metadata=[]]], fields=[a, b])
 
 == Physical Execution Plan ==
 {
@@ -1741,16 +1749,20 @@ SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_COUNT(count$0) AS b]
 
 == Optimized Execution Plan ==
 SortAggregate(isMerge=[true], groupBy=[a], select=[a, Final_COUNT(count$0) AS b])
-+- Sort(orderBy=[a ASC])
-   +- Exchange(distribution=[hash[a]])
-      +- LocalSortAggregate(groupBy=[a], select=[a, Partial_COUNT(b) AS count$0])
-         +- Sort(orderBy=[a ASC])
-            +- SortAggregate(isMerge=[true], groupBy=[a, b], select=[a, b])
-               +- Sort(orderBy=[a ASC, b ASC])
-                  +- Exchange(distribution=[hash[a, b]])
-                     +- LocalSortAggregate(groupBy=[a, b], select=[a, b])
++- Exchange(distribution=[forward])
+   +- Sort(orderBy=[a ASC])
+      +- Exchange(distribution=[hash[a]])
+         +- LocalSortAggregate(groupBy=[a], select=[a, Partial_COUNT(b) AS count$0])
+            +- Exchange(distribution=[forward])
+               +- Sort(orderBy=[a ASC])
+                  +- SortAggregate(isMerge=[true], groupBy=[a, b], select=[a, b])
+                     +- Exchange(distribution=[forward])
                         +- Sort(orderBy=[a ASC, b ASC])
-                           +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b], metadata=[]]], fields=[a, b])
+                           +- Exchange(distribution=[hash[a, b]])
+                              +- LocalSortAggregate(groupBy=[a, b], select=[a, b])
+                                 +- Exchange(distribution=[forward])
+                                    +- Sort(orderBy=[a ASC, b ASC])
+                                       +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[a, b], metadata=[]]], fields=[a, b])
 
 == Physical Execution Plan ==
 {
@@ -2032,9 +2044,10 @@ Calc(select=[b, w$end AS window_end, EXPR$2])
 == Optimized Execution Plan ==
 Calc(select=[b, w$end AS window_end, EXPR$2])
 +- SortWindowAggregate(groupBy=[b], window=[TumblingGroupWindow('w$, rowtime, 900000)], properties=[w$start, w$end, w$rowtime], select=[b, FIRST_VALUE(a) AS EXPR$2])
-   +- Sort(orderBy=[b ASC, rowtime ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[b, rowtime, a], metadata=[]]], fields=[b, rowtime, a])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, rowtime ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[b, rowtime, a], metadata=[]]], fields=[b, rowtime, a])
 
 == Physical Execution Plan ==
 {
@@ -2155,9 +2168,10 @@ Calc(select=[b, w$end AS window_end, EXPR$2])
 == Optimized Execution Plan ==
 Calc(select=[b, w$end AS window_end, EXPR$2])
 +- SortWindowAggregate(groupBy=[b], window=[TumblingGroupWindow('w$, rowtime, 900000)], properties=[w$start, w$end, w$rowtime], select=[b, FIRST_VALUE(a) AS EXPR$2])
-   +- Sort(orderBy=[b ASC, rowtime ASC])
-      +- Exchange(distribution=[hash[b]])
-         +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[b, rowtime, a], metadata=[]]], fields=[b, rowtime, a])
+   +- Exchange(distribution=[forward])
+      +- Sort(orderBy=[b ASC, rowtime ASC])
+         +- Exchange(distribution=[hash[b]])
+            +- TableSourceScan(table=[[default_catalog, default_database, MyTable, project=[b, rowtime, a], metadata=[]]], fields=[b, rowtime, a])
 
 == Physical Execution Plan ==
 {
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/batch/sql/DeadlockBreakupTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/batch/sql/DeadlockBreakupTest.scala
index 581b9ecc769..cd6abc57dcb 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/batch/sql/DeadlockBreakupTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/batch/sql/DeadlockBreakupTest.scala
@@ -17,7 +17,9 @@
  */
 package org.apache.flink.table.planner.plan.batch.sql
 
+import org.apache.flink.api.common.BatchShuffleMode
 import org.apache.flink.api.scala._
+import org.apache.flink.configuration.ExecutionOptions
 import org.apache.flink.table.api._
 import org.apache.flink.table.api.config.{ExecutionConfigOptions, OptimizerConfigOptions}
 import org.apache.flink.table.planner.utils.TableTestBase
@@ -30,6 +32,8 @@ class DeadlockBreakupTest extends TableTestBase {
 
   @Before
   def before(): Unit = {
+    util.tableEnv.getConfig
+      .set(ExecutionOptions.BATCH_SHUFFLE_MODE, BatchShuffleMode.ALL_EXCHANGES_PIPELINED)
     util.addTableSource[(Int, Long, String)]("x", 'a, 'b, 'c)
     util.addTableSource[(Int, Long, String)]("y", 'd, 'e, 'f)
     util.addDataStream[(Int, Long, String)]("t", 'a, 'b, 'c)
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/batch/sql/MultipleInputCreationTest.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/batch/sql/MultipleInputCreationTest.scala
index 1fa35ed1bc0..43a2944e1fe 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/batch/sql/MultipleInputCreationTest.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/plan/batch/sql/MultipleInputCreationTest.scala
@@ -22,7 +22,8 @@ import org.apache.flink.api.common.eventtime.WatermarkStrategy
 import org.apache.flink.api.connector.source.Boundedness
 import org.apache.flink.api.connector.source.mocks.MockSource
 import org.apache.flink.api.scala._
-import org.apache.flink.configuration.ExecutionOptions
+import org.apache.flink.configuration.{ExecutionOptions, JobManagerOptions}
+import org.apache.flink.configuration.JobManagerOptions.SchedulerType
 import org.apache.flink.table.api._
 import org.apache.flink.table.api.config.{ExecutionConfigOptions, OptimizerConfigOptions}
 import org.apache.flink.table.planner.utils.{TableTestBase, TableTestUtil}
@@ -33,7 +34,8 @@ import org.junit.runners.Parameterized
 import org.junit.runners.Parameterized.Parameters
 
 @RunWith(classOf[Parameterized])
-class MultipleInputCreationTest(shuffleMode: BatchShuffleMode) extends TableTestBase {
+class MultipleInputCreationTest(shuffleMode: BatchShuffleMode, schedulerType: SchedulerType)
+  extends TableTestBase {
 
   private val util = batchTestUtil()
 
@@ -44,6 +46,7 @@ class MultipleInputCreationTest(shuffleMode: BatchShuffleMode) extends TableTest
     util.addTableSource[(Int, Long, String, Int)]("z", 'g, 'h, 'i, 'nz)
     util.addDataStream[(Int, Long, String)]("t", 'a, 'b, 'c)
     util.tableConfig.set(ExecutionOptions.BATCH_SHUFFLE_MODE, shuffleMode)
+    util.tableConfig.set(JobManagerOptions.SCHEDULER, schedulerType)
   }
 
   @Test
@@ -353,7 +356,12 @@ class MultipleInputCreationTest(shuffleMode: BatchShuffleMode) extends TableTest
 
 object MultipleInputCreationTest {
 
-  @Parameters(name = "shuffleMode: {0}")
-  def parameters: Array[BatchShuffleMode] =
-    Array(BatchShuffleMode.ALL_EXCHANGES_BLOCKING, BatchShuffleMode.ALL_EXCHANGES_PIPELINED)
+  @Parameters(name = "shuffleMode: {0}, schedulerType: {1}")
+  def parameters(): Array[Array[java.lang.Object]] = {
+    Array(
+      Array(BatchShuffleMode.ALL_EXCHANGES_BLOCKING, SchedulerType.AdaptiveBatch),
+      Array(BatchShuffleMode.ALL_EXCHANGES_BLOCKING, SchedulerType.Default),
+      Array(BatchShuffleMode.ALL_EXCHANGES_PIPELINED, SchedulerType.Default)
+    )
+  }
 }
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/MultipleInputITCase.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/MultipleInputITCase.scala
index 683b7a3eca8..f25d2d96ec9 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/MultipleInputITCase.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/batch/sql/MultipleInputITCase.scala
@@ -20,7 +20,8 @@ package org.apache.flink.table.planner.runtime.batch.sql
 import org.apache.flink.api.common.BatchShuffleMode
 import org.apache.flink.api.common.typeinfo.BasicTypeInfo.{INT_TYPE_INFO, LONG_TYPE_INFO, STRING_TYPE_INFO}
 import org.apache.flink.api.java.typeutils.RowTypeInfo
-import org.apache.flink.configuration.ExecutionOptions
+import org.apache.flink.configuration.{ExecutionOptions, JobManagerOptions}
+import org.apache.flink.configuration.JobManagerOptions.SchedulerType
 import org.apache.flink.streaming.runtime.io.MultipleInputSelectionHandler
 import org.apache.flink.table.api.config.OptimizerConfigOptions
 import org.apache.flink.table.planner.runtime.utils.BatchTestBase
@@ -42,7 +43,8 @@ import scala.util.Random
  * [[org.apache.flink.table.planner.plan.batch.sql.MultipleInputCreationTest]].
  */
 @RunWith(classOf[Parameterized])
-class MultipleInputITCase(shuffleMode: BatchShuffleMode) extends BatchTestBase {
+class MultipleInputITCase(shuffleMode: BatchShuffleMode, schedulerType: SchedulerType)
+  extends BatchTestBase {
 
   @Before
   override def before(): Unit = {
@@ -74,6 +76,7 @@ class MultipleInputITCase(shuffleMode: BatchShuffleMode) extends BatchTestBase {
       MultipleInputITCase.nullables)
 
     tEnv.getConfig.set(ExecutionOptions.BATCH_SHUFFLE_MODE, shuffleMode)
+    tEnv.getConfig.set(JobManagerOptions.SCHEDULER, schedulerType)
   }
 
   @Test
@@ -215,9 +218,14 @@ class MultipleInputITCase(shuffleMode: BatchShuffleMode) extends BatchTestBase {
 
 object MultipleInputITCase {
 
-  @Parameters(name = "shuffleMode: {0}")
-  def parameters: Array[BatchShuffleMode] =
-    Array(BatchShuffleMode.ALL_EXCHANGES_BLOCKING, BatchShuffleMode.ALL_EXCHANGES_PIPELINED)
+  @Parameters(name = "shuffleMode: {0}, schedulerType: {1}")
+  def parameters(): Array[Array[java.lang.Object]] = {
+    Array(
+      Array(BatchShuffleMode.ALL_EXCHANGES_BLOCKING, SchedulerType.AdaptiveBatch),
+      Array(BatchShuffleMode.ALL_EXCHANGES_BLOCKING, SchedulerType.Default),
+      Array(BatchShuffleMode.ALL_EXCHANGES_PIPELINED, SchedulerType.Default)
+    )
+  }
 
   def generateRandomData(): Seq[Row] = {
     val data = new java.util.ArrayList[Row]()
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/utils/BatchTestBase.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/utils/BatchTestBase.scala
index 35c21da04a6..70ecefdf272 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/utils/BatchTestBase.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/runtime/utils/BatchTestBase.scala
@@ -17,10 +17,8 @@
  */
 package org.apache.flink.table.planner.runtime.utils
 
-import org.apache.flink.api.common.BatchShuffleMode
 import org.apache.flink.api.common.typeinfo.TypeInformation
 import org.apache.flink.api.java.tuple.Tuple
-import org.apache.flink.configuration.ExecutionOptions
 import org.apache.flink.streaming.api.datastream.DataStream
 import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment
 import org.apache.flink.table.api._
@@ -537,6 +535,5 @@ object BatchTestBase {
 
   def configForMiniCluster(tableConfig: TableConfig): Unit = {
     tableConfig.set(TABLE_EXEC_RESOURCE_DEFAULT_PARALLELISM, Int.box(DEFAULT_PARALLELISM))
-    tableConfig.set(ExecutionOptions.BATCH_SHUFFLE_MODE, BatchShuffleMode.ALL_EXCHANGES_PIPELINED)
   }
 }
diff --git a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/utils/TableTestBase.scala b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/utils/TableTestBase.scala
index 7bed9442970..f0602ea76e2 100644
--- a/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/utils/TableTestBase.scala
+++ b/flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/utils/TableTestBase.scala
@@ -17,11 +17,9 @@
  */
 package org.apache.flink.table.planner.utils
 
-import org.apache.flink.api.common.BatchShuffleMode
 import org.apache.flink.api.common.typeinfo.{AtomicType, TypeInformation}
 import org.apache.flink.api.java.typeutils.{PojoTypeInfo, RowTypeInfo, TupleTypeInfo}
 import org.apache.flink.api.scala.typeutils.CaseClassTypeInfo
-import org.apache.flink.configuration.ExecutionOptions
 import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.JsonNode
 import org.apache.flink.streaming.api.{environment, TimeCharacteristic}
 import org.apache.flink.streaming.api.datastream.DataStream
@@ -1108,8 +1106,6 @@ abstract class TableTestUtil(
   protected val testingTableEnv: TestingTableEnvironment =
     TestingTableEnvironment.create(setting, catalogManager, tableConfig)
   val tableEnv: TableEnvironment = testingTableEnv
-  tableEnv.getConfig
-    .set(ExecutionOptions.BATCH_SHUFFLE_MODE, BatchShuffleMode.ALL_EXCHANGES_PIPELINED)
 
   private val env: StreamExecutionEnvironment = getPlanner.getExecEnv
 
diff --git a/flink-tests/src/test/java/org/apache/flink/test/scheduling/AdaptiveBatchSchedulerITCase.java b/flink-tests/src/test/java/org/apache/flink/test/scheduling/AdaptiveBatchSchedulerITCase.java
index 5d0e91ae2e5..a6c8981f281 100644
--- a/flink-tests/src/test/java/org/apache/flink/test/scheduling/AdaptiveBatchSchedulerITCase.java
+++ b/flink-tests/src/test/java/org/apache/flink/test/scheduling/AdaptiveBatchSchedulerITCase.java
@@ -103,8 +103,6 @@ public class AdaptiveBatchSchedulerITCase extends TestLogger {
         final Configuration configuration = new Configuration();
         configuration.setString(RestOptions.BIND_PORT, "0");
         configuration.setLong(JobManagerOptions.SLOT_REQUEST_TIMEOUT, 5000L);
-        configuration.set(
-                JobManagerOptions.SCHEDULER, JobManagerOptions.SchedulerType.AdaptiveBatch);
         configuration.setInteger(
                 JobManagerOptions.ADAPTIVE_BATCH_SCHEDULER_MAX_PARALLELISM,
                 DEFAULT_MAX_PARALLELISM);
diff --git a/flink-tests/src/test/java/org/apache/flink/test/scheduling/PipelinedRegionSchedulingITCase.java b/flink-tests/src/test/java/org/apache/flink/test/scheduling/PipelinedRegionSchedulingITCase.java
index ed76f64862d..d931a28a43c 100644
--- a/flink-tests/src/test/java/org/apache/flink/test/scheduling/PipelinedRegionSchedulingITCase.java
+++ b/flink-tests/src/test/java/org/apache/flink/test/scheduling/PipelinedRegionSchedulingITCase.java
@@ -105,6 +105,7 @@ public class PipelinedRegionSchedulingITCase extends TestLogger {
     private JobResult executeSchedulingTest(
             JobGraph jobGraph, int numSlots, Configuration configuration) throws Exception {
         configuration.setLong(JobManagerOptions.SLOT_REQUEST_TIMEOUT, 30000L);
+        configuration.set(JobManagerOptions.SCHEDULER, JobManagerOptions.SchedulerType.Default);
 
         final MiniClusterConfiguration miniClusterConfiguration =
                 new MiniClusterConfiguration.Builder()
diff --git a/flink-tests/src/test/java/org/apache/flink/test/scheduling/SpeculativeSchedulerITCase.java b/flink-tests/src/test/java/org/apache/flink/test/scheduling/SpeculativeSchedulerITCase.java
index 3d316b3ecad..c1f9c936ee0 100644
--- a/flink-tests/src/test/java/org/apache/flink/test/scheduling/SpeculativeSchedulerITCase.java
+++ b/flink-tests/src/test/java/org/apache/flink/test/scheduling/SpeculativeSchedulerITCase.java
@@ -241,8 +241,6 @@ class SpeculativeSchedulerITCase {
                 RestartStrategyOptions.RESTART_STRATEGY_FIXED_DELAY_ATTEMPTS, Integer.MAX_VALUE);
 
         // for speculative execution
-        configuration.set(
-                JobManagerOptions.SCHEDULER, JobManagerOptions.SchedulerType.AdaptiveBatch);
         configuration.set(JobManagerOptions.SPECULATIVE_ENABLED, true);
         // for testing, does not block node by default
         if (!configuration.contains(JobManagerOptions.BLOCK_SLOW_NODE_DURATION)) {


[flink] 01/03: [hotfix] Migrate ExecutionConfigTest to JUnit5.

Posted by zh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zhuzh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git

commit 11a0fc32c9c7171767e43cfbdbbaca5bac94f399
Author: JunRuiLee <jr...@gmail.com>
AuthorDate: Sun Jan 29 11:49:16 2023 +0800

    [hotfix] Migrate ExecutionConfigTest to JUnit5.
---
 .../flink/api/common/ExecutionConfigTest.java      | 111 ++++++++++-----------
 1 file changed, 51 insertions(+), 60 deletions(-)

diff --git a/flink-core/src/test/java/org/apache/flink/api/common/ExecutionConfigTest.java b/flink-core/src/test/java/org/apache/flink/api/common/ExecutionConfigTest.java
index 9a3ccf273e1..91786802cf4 100644
--- a/flink-core/src/test/java/org/apache/flink/api/common/ExecutionConfigTest.java
+++ b/flink-core/src/test/java/org/apache/flink/api/common/ExecutionConfigTest.java
@@ -28,13 +28,12 @@ import org.apache.flink.configuration.Configuration;
 import org.apache.flink.configuration.JobManagerOptions;
 import org.apache.flink.core.testutils.CommonTestUtils;
 import org.apache.flink.util.SerializedValue;
-import org.apache.flink.util.TestLogger;
 
 import com.esotericsoftware.kryo.Kryo;
 import com.esotericsoftware.kryo.Serializer;
 import com.esotericsoftware.kryo.io.Input;
 import com.esotericsoftware.kryo.io.Output;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 import java.io.IOException;
 import java.io.Serializable;
@@ -44,18 +43,13 @@ import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Random;
 
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-public class ExecutionConfigTest extends TestLogger {
+public class ExecutionConfigTest {
 
     @Test
-    public void testDoubleTypeRegistration() {
+    void testDoubleTypeRegistration() {
         ExecutionConfig config = new ExecutionConfig();
         List<Class<?>> types = Arrays.<Class<?>>asList(Double.class, Integer.class, Double.class);
         List<Class<?>> expectedTypes = Arrays.<Class<?>>asList(Double.class, Integer.class);
@@ -67,50 +61,48 @@ public class ExecutionConfigTest extends TestLogger {
         int counter = 0;
 
         for (Class<?> tpe : config.getRegisteredKryoTypes()) {
-            assertEquals(tpe, expectedTypes.get(counter++));
+            assertThat(tpe).isEqualTo(expectedTypes.get(counter++));
         }
 
-        assertEquals(expectedTypes.size(), counter);
+        assertThat(expectedTypes.size()).isEqualTo(counter);
     }
 
     @Test
-    public void testConfigurationOfParallelism() {
+    void testConfigurationOfParallelism() {
         ExecutionConfig config = new ExecutionConfig();
 
         // verify explicit change in parallelism
         int parallelism = 36;
         config.setParallelism(parallelism);
 
-        assertEquals(parallelism, config.getParallelism());
+        assertThat(parallelism).isEqualTo(config.getParallelism());
 
         // verify that parallelism is reset to default flag value
         parallelism = ExecutionConfig.PARALLELISM_DEFAULT;
         config.setParallelism(parallelism);
 
-        assertEquals(parallelism, config.getParallelism());
+        assertThat(parallelism).isEqualTo(config.getParallelism());
     }
 
     @Test
-    public void testDisableGenericTypes() {
+    void testDisableGenericTypes() {
         ExecutionConfig conf = new ExecutionConfig();
         TypeInformation<Object> typeInfo = new GenericTypeInfo<Object>(Object.class);
 
         // by default, generic types are supported
         TypeSerializer<Object> serializer = typeInfo.createSerializer(conf);
-        assertTrue(serializer instanceof KryoSerializer);
+        assertThat(serializer instanceof KryoSerializer).isTrue();
 
         // expect an exception when generic types are disabled
         conf.disableGenericTypes();
-        try {
-            typeInfo.createSerializer(conf);
-            fail("should have failed with an exception");
-        } catch (UnsupportedOperationException e) {
-            // expected
-        }
+        assertThatThrownBy(
+                        () -> typeInfo.createSerializer(conf),
+                        "should have failed with an exception")
+                .isInstanceOf(UnsupportedOperationException.class);
     }
 
     @Test
-    public void testExecutionConfigSerialization() throws IOException, ClassNotFoundException {
+    void testExecutionConfigSerialization() throws IOException, ClassNotFoundException {
         final Random r = new Random();
 
         final int parallelism = 1 + r.nextInt(10);
@@ -153,50 +145,49 @@ public class ExecutionConfigTest extends TestLogger {
         final ExecutionConfig copy2 =
                 new SerializedValue<>(config).deserializeValue(getClass().getClassLoader());
 
-        assertNotNull(copy1);
-        assertNotNull(copy2);
+        assertThat(copy1).isNotNull();
+        assertThat(copy2).isNotNull();
 
-        assertEquals(config, copy1);
-        assertEquals(config, copy2);
+        assertThat(config).isEqualTo(copy1);
+        assertThat(config).isEqualTo(copy2);
 
-        assertEquals(closureCleanerEnabled, copy1.isClosureCleanerEnabled());
-        assertEquals(forceAvroEnabled, copy1.isForceAvroEnabled());
-        assertEquals(forceKryoEnabled, copy1.isForceKryoEnabled());
-        assertEquals(disableGenericTypes, copy1.hasGenericTypesDisabled());
-        assertEquals(objectReuseEnabled, copy1.isObjectReuseEnabled());
-        assertEquals(parallelism, copy1.getParallelism());
+        assertThat(closureCleanerEnabled).isEqualTo(copy1.isClosureCleanerEnabled());
+        assertThat(forceAvroEnabled).isEqualTo(copy1.isForceAvroEnabled());
+        assertThat(forceKryoEnabled).isEqualTo(copy1.isForceKryoEnabled());
+        assertThat(disableGenericTypes).isEqualTo(copy1.hasGenericTypesDisabled());
+        assertThat(objectReuseEnabled).isEqualTo(copy1.isObjectReuseEnabled());
+        assertThat(parallelism).isEqualTo(copy1.getParallelism());
     }
 
     @Test
-    public void testGlobalParametersNotNull() {
+    void testGlobalParametersNotNull() {
         final ExecutionConfig config = new ExecutionConfig();
 
-        assertNotNull(config.getGlobalJobParameters());
+        assertThat(config.getGlobalJobParameters()).isNotNull();
     }
 
     @Test
-    public void testGlobalParametersHashCode() {
+    void testGlobalParametersHashCode() {
         ExecutionConfig config = new ExecutionConfig();
         ExecutionConfig anotherConfig = new ExecutionConfig();
 
-        assertEquals(
-                config.getGlobalJobParameters().hashCode(),
-                anotherConfig.getGlobalJobParameters().hashCode());
+        assertThat(config.getGlobalJobParameters().hashCode())
+                .isEqualTo(anotherConfig.getGlobalJobParameters().hashCode());
     }
 
     @Test
-    public void testReadingDefaultConfig() {
+    void testReadingDefaultConfig() {
         ExecutionConfig executionConfig = new ExecutionConfig();
         Configuration configuration = new Configuration();
 
         // mutate config according to configuration
         executionConfig.configure(configuration, ExecutionConfigTest.class.getClassLoader());
 
-        assertThat(executionConfig, equalTo(new ExecutionConfig()));
+        assertThat(executionConfig).isEqualTo(new ExecutionConfig());
     }
 
     @Test
-    public void testLoadingRegisteredKryoTypesFromConfiguration() {
+    void testLoadingRegisteredKryoTypesFromConfiguration() {
         ExecutionConfig configFromSetters = new ExecutionConfig();
         configFromSetters.registerKryoType(ExecutionConfigTest.class);
         configFromSetters.registerKryoType(TestSerializer1.class);
@@ -213,11 +204,11 @@ public class ExecutionConfigTest extends TestLogger {
         configFromConfiguration.configure(
                 configuration, Thread.currentThread().getContextClassLoader());
 
-        assertThat(configFromConfiguration, equalTo(configFromSetters));
+        assertThat(configFromConfiguration).isEqualTo(configFromSetters);
     }
 
     @Test
-    public void testLoadingRegisteredPojoTypesFromConfiguration() {
+    void testLoadingRegisteredPojoTypesFromConfiguration() {
         ExecutionConfig configFromSetters = new ExecutionConfig();
         configFromSetters.registerPojoType(ExecutionConfigTest.class);
         configFromSetters.registerPojoType(TestSerializer1.class);
@@ -234,11 +225,11 @@ public class ExecutionConfigTest extends TestLogger {
         configFromConfiguration.configure(
                 configuration, Thread.currentThread().getContextClassLoader());
 
-        assertThat(configFromConfiguration, equalTo(configFromSetters));
+        assertThat(configFromConfiguration).isEqualTo(configFromSetters);
     }
 
     @Test
-    public void testLoadingRestartStrategyFromConfiguration() {
+    void testLoadingRestartStrategyFromConfiguration() {
         ExecutionConfig configFromSetters = new ExecutionConfig();
         configFromSetters.setRestartStrategy(
                 RestartStrategies.fixedDelayRestart(10, Time.minutes(2)));
@@ -254,11 +245,11 @@ public class ExecutionConfigTest extends TestLogger {
         configFromConfiguration.configure(
                 configuration, Thread.currentThread().getContextClassLoader());
 
-        assertThat(configFromConfiguration, equalTo(configFromSetters));
+        assertThat(configFromConfiguration).isEqualTo(configFromSetters);
     }
 
     @Test
-    public void testLoadingDefaultKryoSerializersFromConfiguration() {
+    void testLoadingDefaultKryoSerializersFromConfiguration() {
         ExecutionConfig configFromSetters = new ExecutionConfig();
         configFromSetters.addDefaultKryoSerializer(
                 ExecutionConfigTest.class, TestSerializer1.class);
@@ -278,7 +269,7 @@ public class ExecutionConfigTest extends TestLogger {
         configFromConfiguration.configure(
                 configuration, Thread.currentThread().getContextClassLoader());
 
-        assertThat(configFromConfiguration, equalTo(configFromSetters));
+        assertThat(configFromConfiguration).isEqualTo(configFromSetters);
     }
 
     @Test
@@ -298,11 +289,11 @@ public class ExecutionConfigTest extends TestLogger {
         configFromConfiguration.configure(
                 configuration, Thread.currentThread().getContextClassLoader());
 
-        assertThat(configFromConfiguration.isDynamicGraph(), is(expectIsDynamicGraph));
+        assertThat(configFromConfiguration.isDynamicGraph()).isEqualTo(expectIsDynamicGraph);
     }
 
     @Test
-    public void testNotOverridingRegisteredKryoTypesWithDefaultsFromConfiguration() {
+    void testNotOverridingRegisteredKryoTypesWithDefaultsFromConfiguration() {
         ExecutionConfig config = new ExecutionConfig();
         config.registerKryoType(ExecutionConfigTest.class);
         config.registerKryoType(TestSerializer1.class);
@@ -315,11 +306,11 @@ public class ExecutionConfigTest extends TestLogger {
         LinkedHashSet<Object> set = new LinkedHashSet<>();
         set.add(ExecutionConfigTest.class);
         set.add(TestSerializer1.class);
-        assertThat(config.getRegisteredKryoTypes(), equalTo(set));
+        assertThat(config.getRegisteredKryoTypes()).isEqualTo(set);
     }
 
     @Test
-    public void testNotOverridingRegisteredPojoTypesWithDefaultsFromConfiguration() {
+    void testNotOverridingRegisteredPojoTypesWithDefaultsFromConfiguration() {
         ExecutionConfig config = new ExecutionConfig();
         config.registerPojoType(ExecutionConfigTest.class);
         config.registerPojoType(TestSerializer1.class);
@@ -332,11 +323,11 @@ public class ExecutionConfigTest extends TestLogger {
         LinkedHashSet<Object> set = new LinkedHashSet<>();
         set.add(ExecutionConfigTest.class);
         set.add(TestSerializer1.class);
-        assertThat(config.getRegisteredPojoTypes(), equalTo(set));
+        assertThat(config.getRegisteredPojoTypes()).isEqualTo(set);
     }
 
     @Test
-    public void testNotOverridingRestartStrategiesWithDefaultsFromConfiguration() {
+    void testNotOverridingRestartStrategiesWithDefaultsFromConfiguration() {
         ExecutionConfig config = new ExecutionConfig();
         RestartStrategies.RestartStrategyConfiguration restartStrategyConfiguration =
                 RestartStrategies.fixedDelayRestart(10, Time.minutes(2));
@@ -345,11 +336,11 @@ public class ExecutionConfigTest extends TestLogger {
         // mutate config according to configuration
         config.configure(new Configuration(), Thread.currentThread().getContextClassLoader());
 
-        assertThat(config.getRestartStrategy(), equalTo(restartStrategyConfiguration));
+        assertThat(config.getRestartStrategy()).isEqualTo(restartStrategyConfiguration);
     }
 
     @Test
-    public void testNotOverridingDefaultKryoSerializersFromConfiguration() {
+    void testNotOverridingDefaultKryoSerializersFromConfiguration() {
         ExecutionConfig config = new ExecutionConfig();
         config.addDefaultKryoSerializer(ExecutionConfigTest.class, TestSerializer1.class);
         config.addDefaultKryoSerializer(TestSerializer1.class, TestSerializer2.class);
@@ -362,7 +353,7 @@ public class ExecutionConfigTest extends TestLogger {
         LinkedHashMap<Class<?>, Class<? extends Serializer>> serialiers = new LinkedHashMap<>();
         serialiers.put(ExecutionConfigTest.class, TestSerializer1.class);
         serialiers.put(TestSerializer1.class, TestSerializer2.class);
-        assertThat(config.getDefaultKryoSerializerClasses(), equalTo(serialiers));
+        assertThat(config.getDefaultKryoSerializerClasses()).isEqualTo(serialiers);
     }
 
     private static class TestSerializer1 extends Serializer<ExecutionConfigTest>


[flink] 02/03: [hotfix][runtime] remove ExecutionConfig#setScheduler

Posted by zh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zhuzh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git

commit 1bfde8119d242c0954d7e5b6eea74a0dd43e4c7c
Author: JunRuiLee <jr...@gmail.com>
AuthorDate: Sat Jan 28 14:16:54 2023 +0800

    [hotfix][runtime] remove ExecutionConfig#setScheduler
---
 .../org/apache/flink/api/common/ExecutionConfig.java     | 16 +++-------------
 .../planner/plan/batch/sql/ForwardHashExchangeTest.java  |  2 --
 .../planner/runtime/batch/ParallelismSettingTest.java    |  1 -
 .../runtime/batch/sql/ForwardHashExchangeITCase.java     |  2 --
 4 files changed, 3 insertions(+), 18 deletions(-)

diff --git a/flink-core/src/main/java/org/apache/flink/api/common/ExecutionConfig.java b/flink-core/src/main/java/org/apache/flink/api/common/ExecutionConfig.java
index 06473aa9308..f5e027a1939 100644
--- a/flink-core/src/main/java/org/apache/flink/api/common/ExecutionConfig.java
+++ b/flink-core/src/main/java/org/apache/flink/api/common/ExecutionConfig.java
@@ -21,7 +21,6 @@ package org.apache.flink.api.common;
 import org.apache.flink.annotation.Internal;
 import org.apache.flink.annotation.Public;
 import org.apache.flink.annotation.PublicEvolving;
-import org.apache.flink.annotation.VisibleForTesting;
 import org.apache.flink.api.common.restartstrategy.RestartStrategies;
 import org.apache.flink.configuration.ConfigOption;
 import org.apache.flink.configuration.Configuration;
@@ -469,17 +468,6 @@ public class ExecutionConfig implements Serializable, Archiveable<ArchivedExecut
         }
     }
 
-    /**
-     * TODO: this shouldn't exist and shouldn't pollute public API. Tests should change this via
-     * Configuration
-     */
-    @VisibleForTesting
-    @Internal
-    public ExecutionConfig setScheduler(SchedulerType schedulerType) {
-        configuration.set(JobManagerOptions.SCHEDULER, schedulerType);
-        return this;
-    }
-
     @Internal
     public boolean isDynamicGraph() {
         return configuration.get(JobManagerOptions.SCHEDULER) == SchedulerType.AdaptiveBatch;
@@ -1162,7 +1150,9 @@ public class ExecutionConfig implements Serializable, Archiveable<ArchivedExecut
                 .map(c -> loadClasses(c, classLoader, "Could not load kryo type to be registered."))
                 .ifPresent(c -> this.registeredKryoTypes = c);
 
-        configuration.getOptional(JobManagerOptions.SCHEDULER).ifPresent(this::setScheduler);
+        configuration
+                .getOptional(JobManagerOptions.SCHEDULER)
+                .ifPresent(t -> this.configuration.set(JobManagerOptions.SCHEDULER, t));
     }
 
     /**
diff --git a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/batch/sql/ForwardHashExchangeTest.java b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/batch/sql/ForwardHashExchangeTest.java
index c9d3e42edae..33fe021ac3e 100644
--- a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/batch/sql/ForwardHashExchangeTest.java
+++ b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/batch/sql/ForwardHashExchangeTest.java
@@ -17,7 +17,6 @@
 
 package org.apache.flink.table.planner.plan.batch.sql;
 
-import org.apache.flink.configuration.JobManagerOptions.SchedulerType;
 import org.apache.flink.table.api.TableConfig;
 import org.apache.flink.table.api.config.ExecutionConfigOptions;
 import org.apache.flink.table.api.config.OptimizerConfigOptions;
@@ -36,7 +35,6 @@ public class ForwardHashExchangeTest extends TableTestBase {
     public void before() {
         util = batchTestUtil(TableConfig.getDefault());
 
-        util.getStreamEnv().getConfig().setScheduler(SchedulerType.AdaptiveBatch);
         util.tableEnv()
                 .getConfig()
                 .getConfiguration()
diff --git a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/ParallelismSettingTest.java b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/ParallelismSettingTest.java
index 590c8963b4f..1da85aac147 100644
--- a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/ParallelismSettingTest.java
+++ b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/ParallelismSettingTest.java
@@ -18,7 +18,6 @@
 package org.apache.flink.table.planner.runtime.batch;
 
 import org.apache.flink.api.dag.Transformation;
-import org.apache.flink.configuration.JobManagerOptions.SchedulerType;
 import org.apache.flink.table.api.TableConfig;
 import org.apache.flink.table.api.config.ExecutionConfigOptions;
 import org.apache.flink.table.operations.ModifyOperation;
diff --git a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/ForwardHashExchangeITCase.java b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/ForwardHashExchangeITCase.java
index f98ffce0af5..8ba1022f433 100644
--- a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/ForwardHashExchangeITCase.java
+++ b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/batch/sql/ForwardHashExchangeITCase.java
@@ -19,7 +19,6 @@ package org.apache.flink.table.planner.runtime.batch.sql;
 
 import org.apache.flink.api.common.BatchShuffleMode;
 import org.apache.flink.configuration.ExecutionOptions;
-import org.apache.flink.configuration.JobManagerOptions.SchedulerType;
 import org.apache.flink.table.api.config.ExecutionConfigOptions;
 import org.apache.flink.table.planner.factories.TestValuesTableFactory;
 import org.apache.flink.table.planner.runtime.utils.BatchTestBase;
@@ -38,7 +37,6 @@ public class ForwardHashExchangeITCase extends BatchTestBase {
     @Before
     public void before() throws Exception {
         super.before();
-        env().getConfig().setScheduler(SchedulerType.AdaptiveBatch);
         env().disableOperatorChaining();
         tEnv().getConfig()
                 .set(ExecutionOptions.BATCH_SHUFFLE_MODE, BatchShuffleMode.ALL_EXCHANGES_BLOCKING);