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

caogaofei pushed a commit to branch beyyes/joinOperator
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 9f3838a4815447d74215457256c320e3dc63fa02
Author: Beyyes <[email protected]>
AuthorDate: Sat Sep 14 12:18:31 2024 +0800

    AddTableScanColumnsToTypeProviderOptimizer
---
 .../db/queryengine/plan/analyze/TypeProvider.java  |   4 +
 .../plan/relational/analyzer/Analysis.java         |   4 +
 .../planner/iterative/rule/AddJoinIndex.java       |  18 +--
 ...AddTableScanColumnsToTypeProviderOptimizer.java |  61 ++++++++
 .../planner/iterative/rule/MergeLimitWithSort.java |  24 ++--
 .../iterative/rule/PruneJoinChildrenColumns.java   |  77 +++++++++++
 .../relational/planner/iterative/rule/Util.java    |  21 +--
 .../optimizations/DistributedOptimizeFactory.java  |  25 ++--
 .../optimizations/LogicalOptimizeFactory.java      | 153 +++++++++++----------
 .../optimizations/PushPredicateIntoTableScan.java  |   7 +-
 10 files changed, 280 insertions(+), 114 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TypeProvider.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TypeProvider.java
index fc6c56ae599..d599e702d42 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TypeProvider.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/TypeProvider.java
@@ -138,6 +138,10 @@ public class TypeProvider {
     return Collections.unmodifiableMap(tableModelTypes);
   }
 
+  public void setTableModelTypes(Map<Symbol, Type> tableModelTypes) {
+    this.tableModelTypes = tableModelTypes;
+  }
+
   public void serialize(ByteBuffer byteBuffer) {
     ReadWriteIOUtils.write(treeModelTypeMap.size(), byteBuffer);
     for (Map.Entry<String, TSDataType> entry : treeModelTypeMap.entrySet()) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
index bb1678f6598..a9ddeeea37e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
@@ -490,6 +490,10 @@ public class Analysis implements IAnalysis {
     return joins.get(NodeRef.of(join));
   }
 
+  public boolean hasJoinNode() {
+    return !joinUsing.isEmpty() || !joins.isEmpty();
+  }
+
   public void recordSubqueries(Node node, ExpressionAnalysis 
expressionAnalysis) {
     SubqueryAnalysis subqueries =
         this.subQueries.computeIfAbsent(NodeRef.of(node), key -> new 
SubqueryAnalysis());
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/AddJoinIndex.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/AddJoinIndex.java
index 36a4e9638d5..41c33db89eb 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/AddJoinIndex.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/AddJoinIndex.java
@@ -7,7 +7,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Pattern;
 
 import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.Patterns.join;
 
-/** <b>Optimization phase:</b> Logical plan planning. */
+/** <b>Optimization phase:</b> Distributed plan planning. */
 public class AddJoinIndex implements Rule<JoinNode> {
 
   private static final Pattern<JoinNode> PATTERN = join();
@@ -19,19 +19,19 @@ public class AddJoinIndex implements Rule<JoinNode> {
 
   @Override
   public Result apply(JoinNode node, Captures captures, Context context) {
-    ((JoinNode) node).leftTimeColumnIdx =
+    node.leftTimeColumnIdx =
         
node.getLeftChild().getOutputSymbols().indexOf(node.getCriteria().get(0).getLeft());
-    ((JoinNode) node).rightTimeColumnIdx =
+    node.rightTimeColumnIdx =
         
node.getRightChild().getOutputSymbols().indexOf(node.getCriteria().get(0).getRight());
 
-    ((JoinNode) node).leftOutputSymbolIdx = new 
int[node.getLeftOutputSymbols().size()];
-    for (int i = 0; i < ((JoinNode) node).leftOutputSymbolIdx.length; i++) {
-      ((JoinNode) node).leftOutputSymbolIdx[i] =
+    node.leftOutputSymbolIdx = new int[node.getLeftOutputSymbols().size()];
+    for (int i = 0; i < node.leftOutputSymbolIdx.length; i++) {
+      node.leftOutputSymbolIdx[i] =
           
node.getLeftChild().getOutputSymbols().indexOf(node.getLeftOutputSymbols().get(i));
     }
-    ((JoinNode) node).rightOutputSymbolIdx = new 
int[node.getRightOutputSymbols().size()];
-    for (int i = 0; i < ((JoinNode) node).rightOutputSymbolIdx.length; i++) {
-      ((JoinNode) node).rightOutputSymbolIdx[i] =
+    node.rightOutputSymbolIdx = new int[node.getRightOutputSymbols().size()];
+    for (int i = 0; i < node.rightOutputSymbolIdx.length; i++) {
+      node.rightOutputSymbolIdx[i] =
           
node.getRightChild().getOutputSymbols().indexOf(node.getRightOutputSymbols().get(i));
     }
     return Result.empty();
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/AddTableScanColumnsToTypeProviderOptimizer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/AddTableScanColumnsToTypeProviderOptimizer.java
new file mode 100644
index 00000000000..e0b458eee00
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/AddTableScanColumnsToTypeProviderOptimizer.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule;
+
+import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableScanNode;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.PlanOptimizer;
+
+/** <b>Optimization phase:</b> Logical plan planning. */
+public class AddTableScanColumnsToTypeProviderOptimizer implements 
PlanOptimizer {
+
+  @Override
+  public PlanNode optimize(PlanNode plan, PlanOptimizer.Context context) {
+    if (!context.getAnalysis().hasJoinNode()) {
+      return plan;
+    }
+
+    return plan.accept(new Rewriter(context.getQueryContext()), null);
+  }
+
+  private static class Rewriter extends PlanVisitor<PlanNode, Void> {
+
+    private final MPPQueryContext queryContext;
+
+    public Rewriter(MPPQueryContext queryContext) {
+      this.queryContext = queryContext;
+    }
+
+    @Override
+    public PlanNode visitPlan(PlanNode node, Void context) {
+      node.getChildren().forEach(child -> child.accept(this, context));
+      return node;
+    }
+
+    @Override
+    public PlanNode visitTableScan(TableScanNode node, Void context) {
+      node.getAssignments()
+          .forEach((k, v) -> 
queryContext.getTypeProvider().putTableModelType(k, v.getType()));
+      return node;
+    }
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/MergeLimitWithSort.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/MergeLimitWithSort.java
index 92962a0e05d..90948d96a41 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/MergeLimitWithSort.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/MergeLimitWithSort.java
@@ -1,16 +1,22 @@
 /*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
+
 package org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule;
 
 import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.Rule;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/PruneJoinChildrenColumns.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/PruneJoinChildrenColumns.java
new file mode 100644
index 00000000000..66023182067
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/PruneJoinChildrenColumns.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule;
+
+import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.SymbolsExtractor;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.Rule;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.node.JoinNode;
+import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Captures;
+import org.apache.iotdb.db.queryengine.plan.relational.utils.matching.Pattern;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Set;
+
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.Util.restrictChildOutputs;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.Patterns.join;
+
+/**
+ * Joins support output symbol selection, so make any project-off of child 
columns explicit in
+ * project nodes.
+ */
+public class PruneJoinChildrenColumns implements Rule<JoinNode> {
+  private static final Pattern<JoinNode> PATTERN = join();
+
+  @Override
+  public Pattern<JoinNode> getPattern() {
+    return PATTERN;
+  }
+
+  @Override
+  public Result apply(JoinNode joinNode, Captures captures, Context context) {
+    Set<Symbol> globallyUsableInputs =
+        ImmutableSet.<Symbol>builder()
+            .addAll(joinNode.getOutputSymbols())
+            .addAll(
+                
joinNode.getFilter().map(SymbolsExtractor::extractUnique).orElse(ImmutableSet.of()))
+            .build();
+
+    Set<Symbol> leftUsableInputs =
+        ImmutableSet.<Symbol>builder()
+            .addAll(globallyUsableInputs)
+            .addAll(
+                
joinNode.getCriteria().stream().map(JoinNode.EquiJoinClause::getLeft).iterator())
+            // 
.addAll(joinNode.getLeftHashSymbol().map(ImmutableSet::of).orElse(ImmutableSet.of()))
+            .build();
+
+    Set<Symbol> rightUsableInputs =
+        ImmutableSet.<Symbol>builder()
+            .addAll(globallyUsableInputs)
+            .addAll(
+                
joinNode.getCriteria().stream().map(JoinNode.EquiJoinClause::getRight).iterator())
+            // 
.addAll(joinNode.getRightHashSymbol().map(ImmutableSet::of).orElse(ImmutableSet.of()))
+            .build();
+
+    return restrictChildOutputs(
+            context.getIdAllocator(), joinNode, leftUsableInputs, 
rightUsableInputs)
+        .map(Result::ofPlanNode)
+        .orElse(Result.empty());
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/Util.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/Util.java
index e9bcf582773..7447508ab1e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/Util.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/Util.java
@@ -1,15 +1,20 @@
 /*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 package org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule;
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DistributedOptimizeFactory.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DistributedOptimizeFactory.java
index a7221867d79..1b7d893d328 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DistributedOptimizeFactory.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DistributedOptimizeFactory.java
@@ -32,25 +32,28 @@ public class DistributedOptimizeFactory {
   private final List<PlanOptimizer> planOptimizers;
 
   public DistributedOptimizeFactory(PlannerContext plannerContext) {
+    RuleStatsRecorder ruleStats = new RuleStatsRecorder();
+
     IterativeOptimizer topKOptimizer =
         new IterativeOptimizer(
             plannerContext,
-            new RuleStatsRecorder(),
+            ruleStats,
             ImmutableSet.of(
                 new MergeLimitWithMergeSort(), new 
MergeLimitOverProjectWithMergeSort()));
 
     PlanOptimizer sortElimination = new SortElimination();
 
-    IterativeOptimizer limitElimination =
-        new IterativeOptimizer(
-            plannerContext,
-            new RuleStatsRecorder(),
-            ImmutableSet.of(
-                new EliminateLimitWithTableScan(),
-                new EliminateLimitProjectWithTableScan(),
-                new AddJoinIndex()));
-
-    this.planOptimizers = ImmutableList.of(topKOptimizer, sortElimination, 
limitElimination);
+    this.planOptimizers =
+        ImmutableList.of(
+            topKOptimizer,
+            sortElimination,
+            new IterativeOptimizer(
+                plannerContext,
+                ruleStats,
+                ImmutableSet.of(
+                    new EliminateLimitWithTableScan(),
+                    new EliminateLimitProjectWithTableScan(),
+                    new AddJoinIndex())));
   }
 
   public List<PlanOptimizer> getPlanOptimizers() {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/LogicalOptimizeFactory.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/LogicalOptimizeFactory.java
index 629027105d6..1a654eecbb4 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/LogicalOptimizeFactory.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/LogicalOptimizeFactory.java
@@ -24,6 +24,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.planner.PlannerContext;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.IterativeOptimizer;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.Rule;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.RuleStatsRecorder;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.AddTableScanColumnsToTypeProviderOptimizer;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.CanonicalizeExpressions;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.InlineProjections;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.MergeFilters;
@@ -33,6 +34,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.Me
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.PruneAggregationColumns;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.PruneAggregationSourceColumns;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.PruneFilterColumns;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.PruneJoinChildrenColumns;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.PruneJoinColumns;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.PruneLimitColumns;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule.PruneOffsetColumns;
@@ -64,7 +66,6 @@ public class LogicalOptimizeFactory {
     RuleStatsRecorder ruleStats = new RuleStatsRecorder();
 
     PlanOptimizer pushPredicateIntoTableScanOptimizer = new 
PushPredicateIntoTableScan();
-    PlanOptimizer transformSortToStreamSortOptimizer = new 
TransformSortToStreamSort();
 
     Set<Rule<?>> columnPruningRules =
         ImmutableSet.of(
@@ -80,7 +81,8 @@ public class LogicalOptimizeFactory {
             new PruneSortColumns(),
             new PruneTableScanColumns(plannerContext.getMetadata()),
             new PruneTopKColumns(),
-            new PruneJoinColumns());
+            new PruneJoinColumns(),
+            new PruneJoinChildrenColumns());
     IterativeOptimizer columnPruningOptimizer =
         new IterativeOptimizer(plannerContext, ruleStats, columnPruningRules);
 
@@ -138,82 +140,83 @@ public class LogicalOptimizeFactory {
 
     PlanOptimizer pushLimitOffsetIntoTableScanOptimizer = new 
PushLimitOffsetIntoTableScan();
 
-    IterativeOptimizer topKOptimizer =
+    ImmutableList.Builder<PlanOptimizer> optimizerBuilder = 
ImmutableList.builder();
+
+    optimizerBuilder.add(
+        new IterativeOptimizer(
+            plannerContext,
+            ruleStats,
+            ImmutableSet.<Rule<?>>builder()
+                .addAll(columnPruningRules)
+                //                    .addAll(projectionPushdownRules)
+                //                    .addAll(new UnwrapRowSubscript().rules())
+                //                    .addAll(new PushCastIntoRow().rules())
+                .addAll(
+                    ImmutableSet.of(
+                        new MergeFilters(),
+                        new InlineProjections(plannerContext),
+                        new RemoveRedundantIdentityProjections(),
+                        new MergeLimits(),
+                        new RemoveTrivialFilters()
+                        //                        new RemoveRedundantLimit(),
+                        //                        new RemoveRedundantOffset(),
+                        //                        new RemoveRedundantSort(),
+                        //                        new 
RemoveRedundantSortBelowLimitWithTies(),
+                        //                        new RemoveRedundantTopN(),
+                        //                        new 
RemoveRedundantDistinctLimit(),
+                        //                        new 
ReplaceRedundantJoinWithSource(),
+                        //                        new RemoveRedundantJoin(),
+                        //                        new 
ReplaceRedundantJoinWithProject(),
+                        //                        new RemoveRedundantExists(),
+                        //                        new RemoveRedundantWindow(),
+                        //                        new 
SingleDistinctAggregationToGroupBy(),
+                        //                        new MergeLimitWithDistinct(),
+                        //                        new 
PruneCountAggregationOverScalar(metadata),
+                        //                        new 
SimplifyCountOverConstant(plannerContext),
+                        //                        new
+                        // PreAggregateCaseAggregations(plannerContext, 
typeAnalyzer)))
+                        ))
+                .build()),
+        // MergeUnion and related projection pruning rules must run before 
limit pushdown rules,
+        // otherwise
+        // an intermediate limit node will prevent unions from being merged 
later on
         new IterativeOptimizer(
             plannerContext,
             ruleStats,
-            ImmutableSet.of(new MergeLimitWithSort(), new 
MergeLimitOverProjectWithSort()));
-
-    this.planOptimizers =
-        ImmutableList.of(
-            new IterativeOptimizer(
-                plannerContext,
-                ruleStats,
-                ImmutableSet.<Rule<?>>builder()
-                    .addAll(columnPruningRules)
-                    //                    .addAll(projectionPushdownRules)
-                    //                    .addAll(new 
UnwrapRowSubscript().rules())
-                    //                    .addAll(new 
PushCastIntoRow().rules())
-                    .addAll(
-                        ImmutableSet.of(
-                            new MergeFilters(),
-                            new InlineProjections(plannerContext),
-                            new RemoveRedundantIdentityProjections(),
-                            new MergeLimits(),
-                            new RemoveTrivialFilters()
-                            //                        new 
RemoveRedundantLimit(),
-                            //                        new 
RemoveRedundantOffset(),
-                            //                        new 
RemoveRedundantSort(),
-                            //                        new 
RemoveRedundantSortBelowLimitWithTies(),
-                            //                        new 
RemoveRedundantTopN(),
-                            //                        new 
RemoveRedundantDistinctLimit(),
-                            //                        new 
ReplaceRedundantJoinWithSource(),
-                            //                        new 
RemoveRedundantJoin(),
-                            //                        new 
ReplaceRedundantJoinWithProject(),
-                            //                        new 
RemoveRedundantExists(),
-                            //                        new 
RemoveRedundantWindow(),
-                            //                        new 
SingleDistinctAggregationToGroupBy(),
-                            //                        new 
MergeLimitWithDistinct(),
-                            //                        new 
PruneCountAggregationOverScalar(metadata),
-                            //                        new 
SimplifyCountOverConstant(plannerContext),
-                            //                        new
-                            // PreAggregateCaseAggregations(plannerContext, 
typeAnalyzer)))
-                            ))
-                    .build()),
-            // MergeUnion and related projection pruning rules must run before 
limit pushdown rules,
-            // otherwise
-            // an intermediate limit node will prevent unions from being 
merged later on
-            new IterativeOptimizer(
-                plannerContext,
-                ruleStats,
-                ImmutableSet.<Rule<?>>builder()
-                    //                    .addAll(projectionPushdownRules)
-                    .addAll(columnPruningRules)
-                    .addAll(limitPushdownRules)
-                    .addAll(
-                        ImmutableSet.of(
-                            //                        new MergeUnion(),
-                            //                        new 
RemoveEmptyUnionBranches(),
-                            new MergeFilters(),
-                            new RemoveTrivialFilters(),
-                            new MergeLimits(),
-                            new InlineProjections(plannerContext),
-                            new RemoveRedundantIdentityProjections()))
-                    .build()),
-            simplifyOptimizer,
-            unAliasSymbolReferences,
-            columnPruningOptimizer,
-            inlineProjectionLimitFiltersOptimizer,
-            pushPredicateIntoTableScanOptimizer,
-            // redo columnPrune and inlineProjections after 
pushPredicateIntoTableScan
-            columnPruningOptimizer,
-            inlineProjectionLimitFiltersOptimizer,
-            limitPushdownOptimizer,
-            pushLimitOffsetIntoTableScanOptimizer,
-            transformAggregationToStreamableOptimizer,
-            pushAggregationIntoTableScanOptimizer,
-            transformSortToStreamSortOptimizer,
-            topKOptimizer);
+            ImmutableSet.<Rule<?>>builder()
+                //                    .addAll(projectionPushdownRules)
+                .addAll(columnPruningRules)
+                .addAll(limitPushdownRules)
+                .addAll(
+                    ImmutableSet.of(
+                        //                        new MergeUnion(),
+                        //                        new 
RemoveEmptyUnionBranches(),
+                        new MergeFilters(),
+                        new RemoveTrivialFilters(),
+                        new MergeLimits(),
+                        new InlineProjections(plannerContext),
+                        new RemoveRedundantIdentityProjections()))
+                .build()),
+        simplifyOptimizer,
+        unAliasSymbolReferences,
+        columnPruningOptimizer,
+        inlineProjectionLimitFiltersOptimizer,
+        pushPredicateIntoTableScanOptimizer,
+        // redo columnPrune and inlineProjections after 
pushPredicateIntoTableScan
+        columnPruningOptimizer,
+        inlineProjectionLimitFiltersOptimizer,
+        limitPushdownOptimizer,
+        pushLimitOffsetIntoTableScanOptimizer,
+        transformAggregationToStreamableOptimizer,
+        pushAggregationIntoTableScanOptimizer,
+        new TransformSortToStreamSort(),
+        new IterativeOptimizer(
+            plannerContext,
+            ruleStats,
+            ImmutableSet.of(new MergeLimitWithSort(), new 
MergeLimitOverProjectWithSort())),
+        new AddTableScanColumnsToTypeProviderOptimizer());
+
+    this.planOptimizers = optimizerBuilder.build();
   }
 
   public List<PlanOptimizer> getPlanOptimizers() {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushPredicateIntoTableScan.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushPredicateIntoTableScan.java
index 0d66a18ea8c..acce098721c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushPredicateIntoTableScan.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushPredicateIntoTableScan.java
@@ -432,8 +432,10 @@ public class PushPredicateIntoTableScan implements 
PlanOptimizer {
           expression ->
               ReplaceSymbolInExpression.transform(expression, 
tableScanNode.getAssignments()));
       if (tableScanNode.getPushDownPredicate() != null) {
-        ReplaceSymbolInExpression.transform(
-            tableScanNode.getPushDownPredicate(), 
tableScanNode.getAssignments());
+        Expression transformedExpression =
+            ReplaceSymbolInExpression.transform(
+                tableScanNode.getPushDownPredicate(), 
tableScanNode.getAssignments());
+        tableScanNode.setPushDownPredicate(transformedExpression);
       }
 
       int size = tableScanNode.getOutputSymbols().size();
@@ -458,6 +460,7 @@ public class PushPredicateIntoTableScan implements 
PlanOptimizer {
 
       tableScanNode.setOutputSymbols(newTableScanSymbols);
       tableScanNode.setAssignments(newTableScanAssignments);
+
       return new ProjectNode(
           queryId.genPlanNodeId(), tableScanNode, new 
Assignments(projectAssignments));
     }

Reply via email to