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

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


The following commit(s) were added to refs/heads/beyyes/TableModelGrammar_0627 
by this push:
     new 5a78f12a758 fix the calc way of idAndAttributeIndexMap in TableScanNode
5a78f12a758 is described below

commit 5a78f12a758c978ea352328b3bc382cefce40402
Author: Beyyes <[email protected]>
AuthorDate: Mon Jul 1 21:44:55 2024 +0800

    fix the calc way of idAndAttributeIndexMap in TableScanNode
---
 .../TableModelStatementMemorySourceVisitor.java    |   9 +-
 .../plan/relational/metadata/ColumnSchema.java     |   1 +
 .../plan/relational/metadata/MetadataUtil.java     |   2 +-
 .../plan/relational/planner/RelationPlanner.java   |  22 ++++-
 .../plan/relational/planner/Symbol.java            |   5 +
 .../planner/distribute/AddExchangeNodes.java       |  22 +++++
 ...enerator.java => DistributedPlanGenerator.java} | 106 +++++++++++++++++----
 .../planner/distribute/SimplePlanRewriter.java     |  44 ---------
 .../distribute/TableDistributionPlanner.java       |  18 ++--
 .../relational/planner/node/TableScanNode.java     |  15 +--
 .../planner/optimizations/PruneUnUsedColumns.java  |  14 ---
 .../plan/relational/analyzer/AnalyzerTest.java     |  15 +++
 12 files changed, 170 insertions(+), 103 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
index 7b74850287c..6110f65cf17 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
@@ -27,7 +27,7 @@ import 
org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.LogicalQueryPlan;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanGraphPrinter;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
-import 
org.apache.iotdb.db.queryengine.plan.relational.planner.distribute.ExchangeNodeGenerator;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.distribute.DistributedPlanGenerator;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AstVisitor;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Explain;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Node;
@@ -73,10 +73,11 @@ public class TableModelStatementMemorySourceVisitor
     }
 
     // TODO(beyyes) adapt this logic after optimize ExchangeNodeAdder
-    ExchangeNodeGenerator.PlanContext exchangeContext =
-        new ExchangeNodeGenerator.PlanContext(context.getQueryContext(), 
context.getAnalysis());
+    DistributedPlanGenerator.PlanContext exchangeContext =
+        new DistributedPlanGenerator.PlanContext();
     List<PlanNode> distributedPlanNodeResult =
-        new ExchangeNodeGenerator().visitPlan(logicalPlan.getRootNode(), 
exchangeContext);
+        new DistributedPlanGenerator(context.getQueryContext(), 
context.getAnalysis())
+            .visitPlan(logicalPlan.getRootNode(), exchangeContext);
 
     List<String> lines =
         distributedPlanNodeResult
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/ColumnSchema.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/ColumnSchema.java
index bb460c61423..a69d317a420 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/ColumnSchema.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/ColumnSchema.java
@@ -49,6 +49,7 @@ public class ColumnSchema {
 
   public ColumnSchema(
       String name, Type type, boolean hidden, TsTableColumnCategory 
columnCategory) {
+    requireNonNull(name, "name is null");
     requireNonNull(type, "type is null");
 
     this.name = name.toLowerCase(ENGLISH);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/MetadataUtil.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/MetadataUtil.java
index b97141817b0..34a14a70e5e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/MetadataUtil.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/MetadataUtil.java
@@ -54,7 +54,7 @@ public class MetadataUtil {
   }
 
   public static void checkObjectName(String dbName, String objectName) {
-    checkLowerCase(dbName, "schemaName");
+    checkLowerCase(dbName, "dbName");
     checkLowerCase(objectName, "objectName");
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
index fca9a8af675..d85fcc9056c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
@@ -13,6 +13,7 @@
  */
 package org.apache.iotdb.db.queryengine.plan.relational.planner;
 
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.QueryId;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
@@ -42,6 +43,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -98,14 +100,23 @@ public class RelationPlanner extends 
AstVisitor<RelationPlan, Void> {
     ImmutableList.Builder<Symbol> outputSymbolsBuilder = 
ImmutableList.builder();
     ImmutableMap.Builder<Symbol, ColumnSchema> symbolToColumnSchema = 
ImmutableMap.builder();
     Collection<Field> fields = scope.getRelationType().getAllFields();
-
+    // on the basis of that the order of fields is same with the column 
category order of segments
+    // in DeviceEntry
+    Map<Symbol, Integer> idAndAttributeIndexMap = new HashMap<>();
+    int idIndex = 0, attributeIndex = 0;
     for (Field field : fields) {
       Symbol symbol = symbolAllocator.newSymbol(field);
       outputSymbolsBuilder.add(symbol);
+      TsTableColumnCategory category = field.getColumnCategory();
       symbolToColumnSchema.put(
           symbol,
           new ColumnSchema(
-              field.getName().get(), field.getType(), field.isHidden(), 
field.getColumnCategory()));
+              field.getName().orElse(null), field.getType(), field.isHidden(), 
category));
+      if (category == TsTableColumnCategory.ID) {
+        idAndAttributeIndexMap.put(symbol, idIndex++);
+      } else if (category == TsTableColumnCategory.ATTRIBUTE) {
+        idAndAttributeIndexMap.put(symbol, attributeIndex++);
+      }
     }
 
     List<Symbol> outputSymbols = outputSymbolsBuilder.build();
@@ -113,13 +124,16 @@ public class RelationPlanner extends 
AstVisitor<RelationPlan, Void> {
     if (!qualifiedName.getPrefix().isPresent()) {
       throw new IllegalStateException("Table " + table.getName() + " has no 
prefix!");
     }
+
     TableScanNode tableScanNode =
         new TableScanNode(
             idAllocator.genPlanNodeId(),
             new QualifiedObjectName(
-                qualifiedName.getPrefix().get().toString(), 
qualifiedName.getSuffix()),
+                
qualifiedName.getPrefix().map(QualifiedName::toString).orElse(null),
+                qualifiedName.getSuffix()),
             outputSymbols,
-            symbolToColumnSchema.build());
+            symbolToColumnSchema.build(),
+            idAndAttributeIndexMap);
 
     return new RelationPlan(tableScanNode, scope, outputSymbols);
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/Symbol.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/Symbol.java
index 4f48df0890f..eb90d8183e5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/Symbol.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/Symbol.java
@@ -44,6 +44,11 @@ public class Symbol implements Comparable<Symbol> {
     this.name = name;
   }
 
+  public static Symbol of(String name) {
+    requireNonNull(name, "name is null");
+    return new Symbol(name);
+  }
+
   public String getName() {
     return name;
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/AddExchangeNodes.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/AddExchangeNodes.java
new file mode 100644
index 00000000000..e8ff90a5598
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/AddExchangeNodes.java
@@ -0,0 +1,22 @@
+/*
+ * 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.distribute;
+
+public class AddExchangeNodes {}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/ExchangeNodeGenerator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/DistributedPlanGenerator.java
similarity index 72%
rename from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/ExchangeNodeGenerator.java
rename to 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/DistributedPlanGenerator.java
index 809d1398aee..2cfced93aae 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/ExchangeNodeGenerator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/DistributedPlanGenerator.java
@@ -19,6 +19,8 @@ import 
org.apache.iotdb.db.queryengine.plan.planner.distribution.NodeDistributio
 import 
org.apache.iotdb.db.queryengine.plan.planner.distribution.NodeDistributionType;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.WritePlanNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.metedata.read.AbstractSchemaMergeNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.metedata.read.SchemaQueryMergeNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.metedata.read.TableDeviceSourceNode;
@@ -29,7 +31,9 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.DeviceEntry;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.OrderingScheme;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.SortOrder;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.node.FilterNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.MergeSortNode;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.ProjectNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableScanNode;
 
 import java.util.ArrayList;
@@ -40,9 +44,40 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static com.google.common.collect.ImmutableList.toImmutableList;
 import static 
org.apache.iotdb.db.queryengine.plan.planner.distribution.NodeDistributionType.SAME_WITH_ALL_CHILDREN;
 
-public class ExchangeNodeGenerator extends 
SimplePlanRewriter<ExchangeNodeGenerator.PlanContext> {
+public class DistributedPlanGenerator
+    extends PlanVisitor<List<PlanNode>, DistributedPlanGenerator.PlanContext> {
+  private final MPPQueryContext queryContext;
+  private final Analysis analysis;
+
+  public DistributedPlanGenerator(MPPQueryContext queryContext, Analysis 
analysis) {
+    this.queryContext = queryContext;
+    this.analysis = analysis;
+  }
+
+  public List<PlanNode> genResult(PlanNode node, PlanContext context) {
+    return node.accept(this, context);
+  }
+
+  @Override
+  public List<PlanNode> visitPlan(PlanNode node, 
DistributedPlanGenerator.PlanContext context) {
+    if (node instanceof WritePlanNode) {
+      return Collections.singletonList(node);
+    }
+
+    List<List<PlanNode>> children =
+        node.getChildren().stream()
+            .map(child -> child.accept(this, context))
+            .collect(toImmutableList());
+
+    PlanNode newNode = node.clone();
+    for (List<PlanNode> planNodes : children) {
+      planNodes.forEach(newNode::addChild);
+    }
+    return Collections.singletonList(newNode);
+  }
 
   @Override
   public List<PlanNode> visitTableScan(TableScanNode node, PlanContext 
context) {
@@ -51,8 +86,7 @@ public class ExchangeNodeGenerator extends 
SimplePlanRewriter<ExchangeNodeGenera
 
     for (DeviceEntry deviceEntry : node.getDeviceEntries()) {
       List<TRegionReplicaSet> regionReplicaSets =
-          context
-              .analysis
+          analysis
               .getDataPartitionInfo()
               .getDataRegionReplicaSetWithTimeFilter(
                   node.getQualifiedObjectName().getDatabaseName(),
@@ -65,7 +99,7 @@ public class ExchangeNodeGenerator extends 
SimplePlanRewriter<ExchangeNodeGenera
                 k -> {
                   TableScanNode scanNode =
                       new TableScanNode(
-                          context.queryContext.getQueryId().genPlanNodeId(),
+                          queryContext.getQueryId().genPlanNodeId(),
                           node.getQualifiedObjectName(),
                           node.getOutputSymbols(),
                           node.getAssignments(),
@@ -90,14 +124,12 @@ public class ExchangeNodeGenerator extends 
SimplePlanRewriter<ExchangeNodeGenera
       OrderingScheme orderingScheme = new OrderingScheme(orderBy, orderings);
       MergeSortNode mergeSortNode =
           new MergeSortNode(
-              context.queryContext.getQueryId().genPlanNodeId(),
-              orderingScheme,
-              node.getOutputSymbols());
+              queryContext.getQueryId().genPlanNodeId(), orderingScheme, 
node.getOutputSymbols());
 
       for (Map.Entry<TRegionReplicaSet, TableScanNode> entry : 
tableScanNodeMap.entrySet()) {
         TRegionReplicaSet regionReplicaSet = entry.getKey();
         TableScanNode subTableScanNode = entry.getValue();
-        
subTableScanNode.setPlanNodeId(context.queryContext.getQueryId().genPlanNodeId());
+        
subTableScanNode.setPlanNodeId(queryContext.getQueryId().genPlanNodeId());
         subTableScanNode.setRegionReplicaSet(regionReplicaSet);
         context.nodeDistributionMap.put(
             subTableScanNode.getPlanNodeId(),
@@ -110,8 +142,7 @@ public class ExchangeNodeGenerator extends 
SimplePlanRewriter<ExchangeNodeGenera
               mergeSortNode.getPlanNodeId(),
               new NodeDistribution(SAME_WITH_ALL_CHILDREN, regionReplicaSet));
         } else {
-          ExchangeNode exchangeNode =
-              new 
ExchangeNode(context.queryContext.getQueryId().genPlanNodeId());
+          ExchangeNode exchangeNode = new 
ExchangeNode(queryContext.getQueryId().genPlanNodeId());
           exchangeNode.addChild(subTableScanNode);
           mergeSortNode.addChild(exchangeNode);
         }
@@ -123,6 +154,46 @@ public class ExchangeNodeGenerator extends 
SimplePlanRewriter<ExchangeNodeGenera
     }
   }
 
+  @Override
+  public List<PlanNode> visitFilter(FilterNode filterNode, PlanContext 
context) {
+    List<PlanNode> childrenNodes = filterNode.getChild().accept(this, context);
+    if (childrenNodes.size() == 1) {
+      filterNode.setChild(childrenNodes.get(0));
+      return Collections.singletonList(filterNode);
+    }
+
+    List<PlanNode> result = new ArrayList<>();
+    for (PlanNode child : childrenNodes) {
+      FilterNode newFilterNode =
+          new FilterNode(
+              queryContext.getQueryId().genPlanNodeId(), child, 
filterNode.getPredicate());
+      result.add(newFilterNode);
+    }
+
+    return result;
+  }
+
+  @Override
+  public List<PlanNode> visitProject(ProjectNode projectNode, PlanContext 
context) {
+    List<PlanNode> childrenNodes = projectNode.getChild().accept(this, 
context);
+    if (childrenNodes.size() == 1) {
+      projectNode.setChild(childrenNodes.get(0));
+      return Collections.singletonList(projectNode);
+    }
+
+    List<PlanNode> result = new ArrayList<>();
+    for (PlanNode child : childrenNodes) {
+      ProjectNode newProjectNode =
+          new ProjectNode(
+              queryContext.getQueryId().genPlanNodeId(), child, 
projectNode.getAssignments());
+      result.add(newProjectNode);
+    }
+
+    return result;
+  }
+
+  // ------------------- schema related interface 
---------------------------------------------
+
   @Override
   public List<PlanNode> visitSchemaQueryMerge(SchemaQueryMergeNode node, 
PlanContext context) {
     return Collections.singletonList(
@@ -135,8 +206,7 @@ public class ExchangeNodeGenerator extends 
SimplePlanRewriter<ExchangeNodeGenera
 
     String database = ((TableDeviceSourceNode) 
node.getChildren().get(0)).getDatabase();
     Set<TRegionReplicaSet> schemaRegionSet = new HashSet<>();
-    context
-        .analysis
+    analysis
         .getSchemaPartitionInfo()
         .getSchemaPartitionMap()
         .get(database)
@@ -146,7 +216,7 @@ public class ExchangeNodeGenerator extends 
SimplePlanRewriter<ExchangeNodeGenera
     for (PlanNode child : node.getChildren()) {
       for (TRegionReplicaSet schemaRegion : schemaRegionSet) {
         SourceNode clonedChild = (SourceNode) child.clone();
-        
clonedChild.setPlanNodeId(context.queryContext.getQueryId().genPlanNodeId());
+        clonedChild.setPlanNodeId(queryContext.getQueryId().genPlanNodeId());
         clonedChild.setRegionReplicaSet(schemaRegion);
         root.addChild(clonedChild);
       }
@@ -176,7 +246,7 @@ public class ExchangeNodeGenerator extends 
SimplePlanRewriter<ExchangeNodeGenera
                   .getRegion()
                   
.equals(context.getNodeDistribution(child.getPlanNodeId()).getRegion())) {
                 ExchangeNode exchangeNode =
-                    new 
ExchangeNode(context.queryContext.getQueryId().genPlanNodeId());
+                    new 
ExchangeNode(queryContext.getQueryId().genPlanNodeId());
                 exchangeNode.setChild(child);
                 
exchangeNode.setOutputColumnNames(child.getOutputColumnNames());
                 context.hasExchangeNode = true;
@@ -195,17 +265,11 @@ public class ExchangeNodeGenerator extends 
SimplePlanRewriter<ExchangeNodeGenera
   }
 
   public static class PlanContext {
-    final MPPQueryContext queryContext;
     final Map<PlanNodeId, NodeDistribution> nodeDistributionMap;
-    TRegionReplicaSet mostlyUsedDataRegion;
     boolean hasExchangeNode = false;
 
-    final Analysis analysis;
-
-    public PlanContext(MPPQueryContext queryContext, Analysis analysis) {
-      this.queryContext = queryContext;
+    public PlanContext() {
       this.nodeDistributionMap = new HashMap<>();
-      this.analysis = analysis;
     }
 
     public NodeDistribution getNodeDistribution(PlanNodeId nodeId) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/SimplePlanRewriter.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/SimplePlanRewriter.java
deleted file mode 100644
index 9c5ac404c6b..00000000000
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/SimplePlanRewriter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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
- *
- *     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.distribute;
-
-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.planner.plan.node.WritePlanNode;
-
-import java.util.Collections;
-import java.util.List;
-
-import static com.google.common.collect.ImmutableList.toImmutableList;
-
-public class SimplePlanRewriter<C> extends PlanVisitor<List<PlanNode>, C> {
-
-  @Override
-  public List<PlanNode> visitPlan(PlanNode node, C context) {
-    if (node instanceof WritePlanNode) {
-      return Collections.singletonList(node);
-    }
-
-    List<List<PlanNode>> children =
-        node.getChildren().stream()
-            .map(child -> child.accept(this, context))
-            .collect(toImmutableList());
-
-    PlanNode newNode = node.clone();
-    for (List<PlanNode> planNodes : children) {
-      planNodes.forEach(newNode::addChild);
-    }
-    return Collections.singletonList(newNode);
-  }
-}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributionPlanner.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributionPlanner.java
index 684bffc6acb..8eb0f0c90fd 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributionPlanner.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributionPlanner.java
@@ -50,16 +50,16 @@ public class TableDistributionPlanner {
   }
 
   public DistributedQueryPlan plan() {
-    ExchangeNodeGenerator.PlanContext exchangeContext =
-        new ExchangeNodeGenerator.PlanContext(mppQueryContext, analysis);
-    List<PlanNode> distributedPlanNodeResult =
-        new ExchangeNodeGenerator().visitPlan(logicalQueryPlan.getRootNode(), 
exchangeContext);
+    DistributedPlanGenerator.PlanContext planContext = new 
DistributedPlanGenerator.PlanContext();
+    List<PlanNode> distributedPlanResult =
+        new DistributedPlanGenerator(mppQueryContext, analysis)
+            .genResult(logicalQueryPlan.getRootNode(), planContext);
 
-    if (distributedPlanNodeResult.size() != 1) {
+    if (distributedPlanResult.size() != 1) {
       throw new IllegalStateException("root node must return only one");
     }
 
-    PlanNode outputNodeWithExchange = distributedPlanNodeResult.get(0);
+    PlanNode outputNodeWithExchange = distributedPlanResult.get(0);
     if (analysis.getStatement() instanceof Query) {
       analysis
           .getRespDatasetHeader()
@@ -69,7 +69,7 @@ public class TableDistributionPlanner {
                   .filter(e -> 
!TIMESTAMP_EXPRESSION_STRING.equalsIgnoreCase(e))
                   .collect(Collectors.toList()));
     }
-    adjustUpStream(outputNodeWithExchange, exchangeContext);
+    adjustUpStream(outputNodeWithExchange, planContext);
 
     SubPlan subPlan =
         new SubPlanGenerator()
@@ -124,7 +124,7 @@ public class TableDistributionPlanner {
     rootInstance.getFragment().setPlanNodeTree(sinkNode);
   }
 
-  private void adjustUpStream(PlanNode root, ExchangeNodeGenerator.PlanContext 
exchangeContext) {
+  private void adjustUpStream(PlanNode root, 
DistributedPlanGenerator.PlanContext exchangeContext) {
     if (!exchangeContext.hasExchangeNode) {
       return;
     }
@@ -134,7 +134,7 @@ public class TableDistributionPlanner {
 
   private void adjustUpStreamHelper(
       PlanNode root,
-      ExchangeNodeGenerator.PlanContext exchangeContext,
+      DistributedPlanGenerator.PlanContext exchangeContext,
       Map<TRegionReplicaSet, IdentitySinkNode> regionNodemap) {
     for (PlanNode child : root.getChildren()) {
       adjustUpStreamHelper(child, exchangeContext, regionNodemap);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
index d90f5af29a1..d83d2785f19 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
@@ -51,7 +51,12 @@ public class TableScanNode extends SourceNode {
   private Map<Symbol, ColumnSchema> assignments;
 
   private List<DeviceEntry> deviceEntries;
-  private Map<Symbol, Integer> idAndAttributeIndexMap;
+
+  // Indicates the respective index order of ID and Attribute columns in 
DeviceEntry.
+  // For example, for DeviceEntry 
`table1.tag1.tag2.attribute1.attribute2.s1.s2`, the content of
+  // `idAndAttributeIndexMap` will
+  // be `tag1: 0, tag2: 1, attribute1: 0, attribute2: 1`.
+  private final Map<Symbol, Integer> idAndAttributeIndexMap;
 
   // The order to traverse the data.
   // Currently, we only support TIMESTAMP_ASC and TIMESTAMP_DESC here.
@@ -85,11 +90,13 @@ public class TableScanNode extends SourceNode {
       PlanNodeId id,
       QualifiedObjectName qualifiedObjectName,
       List<Symbol> outputSymbols,
-      Map<Symbol, ColumnSchema> assignments) {
+      Map<Symbol, ColumnSchema> assignments,
+      Map<Symbol, Integer> idAndAttributeIndexMap) {
     super(id);
     this.qualifiedObjectName = qualifiedObjectName;
     this.outputSymbols = outputSymbols;
     this.assignments = assignments;
+    this.idAndAttributeIndexMap = idAndAttributeIndexMap;
   }
 
   public TableScanNode(
@@ -368,10 +375,6 @@ public class TableScanNode extends SourceNode {
     return this.idAndAttributeIndexMap;
   }
 
-  public void setIdAndAttributeIndexMap(Map<Symbol, Integer> 
idAndAttributeIndexMap) {
-    this.idAndAttributeIndexMap = idAndAttributeIndexMap;
-  }
-
   public Ordering getScanOrder() {
     return this.scanOrder;
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PruneUnUsedColumns.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PruneUnUsedColumns.java
index 8b1ce55f7ae..13bec944edd 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PruneUnUsedColumns.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PruneUnUsedColumns.java
@@ -14,7 +14,6 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations;
 
-import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
@@ -126,19 +125,6 @@ public class PruneUnUsedColumns implements 
RelationalPlanOptimizer {
       }
       node.setOutputSymbols(newOutputSymbols);
       node.setAssignments(newAssignments);
-
-      int IDIdx = 0, attributeIdx = 0;
-      Map<Symbol, Integer> idAndAttributeIndexMap = new 
HashMap<>(node.getAssignments().size());
-      for (Symbol symbol : node.getOutputSymbols()) {
-        ColumnSchema columnSchema = node.getAssignments().get(symbol);
-        if (TsTableColumnCategory.ID.equals(columnSchema.getColumnCategory())) 
{
-          idAndAttributeIndexMap.put(symbol, IDIdx++);
-        } else if 
(TsTableColumnCategory.ATTRIBUTE.equals(columnSchema.getColumnCategory())) {
-          idAndAttributeIndexMap.put(symbol, attributeIdx++);
-        }
-      }
-      node.setIdAndAttributeIndexMap(idAndAttributeIndexMap);
-
       return node;
     }
   }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
index 0369e96d111..77162d0a330 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
@@ -37,6 +37,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectN
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableHandle;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableSchema;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.LogicalPlanner;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.distribute.TableDistributionPlanner;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.FilterNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.LimitNode;
@@ -60,6 +61,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.stream.Stream;
 
 import static 
org.apache.iotdb.db.queryengine.execution.warnings.WarningCollector.NOOP;
 import static 
org.apache.iotdb.db.queryengine.plan.statement.component.Ordering.ASC;
@@ -237,6 +239,19 @@ public class AnalyzerTest {
     assertNotNull(tableScanNode.getPushDownPredicate());
     assertEquals("(\"s1\" > 1)", 
tableScanNode.getPushDownPredicate().toString());
     assertFalse(tableScanNode.getTimePredicate().isPresent());
+    assertTrue(
+        Stream.of(
+                Symbol.of("tag1"),
+                Symbol.of("tag2"),
+                Symbol.of("tag3"),
+                Symbol.of("attr1"),
+                Symbol.of("attr2"))
+            .allMatch(tableScanNode.getIdAndAttributeIndexMap()::containsKey));
+    assertEquals(0, (int) 
tableScanNode.getIdAndAttributeIndexMap().get(Symbol.of("tag1")));
+    assertEquals(1, (int) 
tableScanNode.getIdAndAttributeIndexMap().get(Symbol.of("tag2")));
+    assertEquals(2, (int) 
tableScanNode.getIdAndAttributeIndexMap().get(Symbol.of("tag3")));
+    assertEquals(0, (int) 
tableScanNode.getIdAndAttributeIndexMap().get(Symbol.of("attr1")));
+    assertEquals(1, (int) 
tableScanNode.getIdAndAttributeIndexMap().get(Symbol.of("attr2")));
     assertEquals(
         Arrays.asList("time", "tag1", "attr1", "s1", "s2"), 
tableScanNode.getOutputColumnNames());
   }

Reply via email to