You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by hu...@apache.org on 2022/09/07 10:37:16 UTC

[iotdb] branch lmh/TypeProviderOpt updated (7cd1965c52 -> 17dbab6890)

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

hui pushed a change to branch lmh/TypeProviderOpt
in repository https://gitbox.apache.org/repos/asf/iotdb.git


    from 7cd1965c52 add ExpressionTypeAnalyzer
     new 13f6ac54a7 finish ExpressionTypeAnalyzer
     new babbe9c671 remove inferTypes in Expression
     new 000c970689 add SymbolAllocator
     new 9f3e3ccf1b remove SymbolAllocator
     new c9981379ee split types to sub plans
     new 7d888bf409 re-analyze expression in OperatorTreeGenerator
     new 17dbab6890 bug fix

The 7 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:
 .../iotdb/db/mpp/common/MPPQueryContext.java       |   7 +
 .../apache/iotdb/db/mpp/plan/analyze/Analysis.java |  23 +-
 .../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java  | 137 +++++-------
 .../apache/iotdb/db/mpp/plan/analyze/Analyzer.java |   5 +-
 .../db/mpp/plan/analyze/ExpressionAnalyzer.java    | 118 ++--------
 .../mpp/plan/analyze/ExpressionTypeAnalyzer.java   | 238 ++++++++++++++++++++-
 .../mpp/plan/analyze/GroupByLevelController.java   |   4 +-
 .../iotdb/db/mpp/plan/analyze/TypeProvider.java    |  21 +-
 .../iotdb/db/mpp/plan/expression/Expression.java   |  24 +--
 .../binary/ArithmeticBinaryExpression.java         |  25 +--
 .../plan/expression/binary/BinaryExpression.java   |   8 +-
 .../expression/binary/CompareBinaryExpression.java |  54 +----
 .../expression/binary/LogicBinaryExpression.java   |  15 +-
 .../mpp/plan/expression/leaf/ConstantOperand.java  |   7 -
 .../db/mpp/plan/expression/leaf/LeafOperand.java   |   5 +-
 .../plan/expression/leaf/TimeSeriesOperand.java    |   7 -
 .../mpp/plan/expression/leaf/TimestampOperand.java |   8 -
 .../plan/expression/multi/FunctionExpression.java  |  44 +---
 .../plan/expression/ternary/BetweenExpression.java |  20 +-
 .../plan/expression/ternary/TernaryExpression.java |  11 +-
 .../db/mpp/plan/expression/unary/InExpression.java |  18 +-
 .../plan/expression/unary/IsNullExpression.java    |  18 +-
 .../mpp/plan/expression/unary/LikeExpression.java  |  20 +-
 .../plan/expression/unary/LogicNotExpression.java  |  20 +-
 .../plan/expression/unary/NegationExpression.java  |  26 +--
 .../plan/expression/unary/RegularExpression.java   |  20 +-
 .../mpp/plan/expression/unary/UnaryExpression.java |   7 +-
 .../visitor/ColumnTransformerVisitor.java          |  69 +++---
 .../plan/expression/visitor/ExpressionVisitor.java |  63 +++++-
 .../db/mpp/plan/planner/LogicalPlanBuilder.java    |  59 +++--
 .../db/mpp/plan/planner/LogicalPlanVisitor.java    |  40 ++--
 .../db/mpp/plan/planner/OperatorTreeGenerator.java |  27 ++-
 .../db/mpp/plan/planner/SubPlanTypeExtractor.java  |  75 +++++++
 .../SimpleFragmentParallelPlanner.java             |   2 +-
 .../plan/planner/distribution/SourceRewriter.java  |  18 +-
 .../db/mpp/plan/planner/plan/PlanFragment.java     |   9 +-
 ...tionRelatedNode.java => SimplePlanVisitor.java} |  12 +-
 .../mpp/plan/plan/distribution/LastQueryTest.java  |  26 ++-
 38 files changed, 688 insertions(+), 622 deletions(-)
 create mode 100644 server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java
 copy server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/{IPartitionRelatedNode.java => SimplePlanVisitor.java} (78%)


[iotdb] 05/07: split types to sub plans

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

hui pushed a commit to branch lmh/TypeProviderOpt
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit c9981379eed90a866b5c094e96e59592e26692e7
Author: Minghui Liu <li...@foxmail.com>
AuthorDate: Wed Sep 7 16:17:44 2022 +0800

    split types to sub plans
---
 .../iotdb/db/mpp/common/MPPQueryContext.java       |  7 +++
 .../apache/iotdb/db/mpp/plan/analyze/Analysis.java | 15 ++++--
 .../iotdb/db/mpp/plan/analyze/TypeProvider.java    | 21 +++-----
 .../db/mpp/plan/planner/LogicalPlanBuilder.java    | 59 +++++++++++++++++-----
 .../db/mpp/plan/planner/LogicalPlanVisitor.java    | 40 +++++++--------
 .../db/mpp/plan/planner/SubPlanTypeExtractor.java  | 54 ++++++++++++++++++++
 .../SimpleFragmentParallelPlanner.java             |  2 +-
 .../plan/planner/distribution/SourceRewriter.java  | 18 ++++---
 .../db/mpp/plan/planner/plan/PlanFragment.java     |  9 +++-
 .../plan/planner/plan/node/SimplePlanVisitor.java  | 30 +++++++++++
 .../mpp/plan/plan/distribution/LastQueryTest.java  | 26 ++++++----
 11 files changed, 208 insertions(+), 73 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/common/MPPQueryContext.java b/server/src/main/java/org/apache/iotdb/db/mpp/common/MPPQueryContext.java
index 91d4d85f89..8f4e53470d 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/common/MPPQueryContext.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/common/MPPQueryContext.java
@@ -20,6 +20,7 @@ package org.apache.iotdb.db.mpp.common;
 
 import org.apache.iotdb.common.rpc.thrift.TEndPoint;
 import org.apache.iotdb.db.mpp.plan.analyze.QueryType;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 
 import java.util.LinkedList;
 import java.util.List;
@@ -45,6 +46,8 @@ public class MPPQueryContext {
   // onto this node.
   private final List<TEndPoint> endPointBlackList;
 
+  private final TypeProvider typeProvider = new TypeProvider();
+
   public MPPQueryContext(QueryId queryId) {
     this.queryId = queryId;
     this.endPointBlackList = new LinkedList<>();
@@ -129,4 +132,8 @@ public class MPPQueryContext {
   public List<TEndPoint> getEndPointBlackList() {
     return endPointBlackList;
   }
+
+  public TypeProvider getTypeProvider() {
+    return typeProvider;
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
index c106572837..d45d98e22c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
@@ -65,7 +65,6 @@ public class Analysis {
 
   // map from output column name (for every node) to its datatype
   private final Map<NodeRef<Expression>, TSDataType> expressionTypes = new LinkedHashMap<>();
-  private TypeProvider typeProvider;
 
   private boolean finishQueryAfterAnalyze;
 
@@ -129,6 +128,8 @@ public class Analysis {
   // Query Common Analysis (above DeviceView)
   /////////////////////////////////////////////////////////////////////////////////////////////////
 
+  private List<Pair<Expression, String>> outputExpressions;
+
   // indicate is there a value filter
   private boolean hasValueFilter = false;
 
@@ -223,10 +224,6 @@ public class Analysis {
     this.respDatasetHeader = respDatasetHeader;
   }
 
-  public TypeProvider getTypeProvider() {
-    return typeProvider;
-  }
-
   public TSDataType getType(Expression expression) {
     TSDataType type = expressionTypes.get(NodeRef.of(expression));
     checkArgument(type != null, "Expression not analyzed: %s", expression);
@@ -460,4 +457,12 @@ public class Analysis {
   public void addTypes(Map<NodeRef<Expression>, TSDataType> types) {
     this.expressionTypes.putAll(types);
   }
+
+  public List<Pair<Expression, String>> getOutputExpressions() {
+    return outputExpressions;
+  }
+
+  public void setOutputExpressions(List<Pair<Expression, String>> outputExpressions) {
+    this.outputExpressions = outputExpressions;
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java
index 27ec021ff4..1c3bdd3b56 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java
@@ -22,8 +22,6 @@ package org.apache.iotdb.db.mpp.plan.analyze;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
-import com.google.common.collect.ImmutableMap;
-
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -37,10 +35,6 @@ public class TypeProvider {
 
   private final Map<String, TSDataType> typeMap;
 
-  public static TypeProvider empty() {
-    return new TypeProvider(ImmutableMap.of());
-  }
-
   public TypeProvider() {
     this.typeMap = new HashMap<>();
   }
@@ -49,16 +43,17 @@ public class TypeProvider {
     this.typeMap = typeMap;
   }
 
-  public TSDataType getType(String path) {
-    checkState(typeMap.containsKey(path), String.format("no data type found for path: %s", path));
-    return typeMap.get(path);
+  public TSDataType getType(String symbol) {
+    checkState(
+        typeMap.containsKey(symbol), String.format("no data type found for symbol: %s", symbol));
+    return typeMap.get(symbol);
   }
 
-  public void setType(String path, TSDataType dataType) {
+  public void setType(String symbol, TSDataType dataType) {
     checkState(
-        !typeMap.containsKey(path) || typeMap.get(path) == dataType,
-        String.format("inconsistent data type for path: %s", path));
-    this.typeMap.put(path, dataType);
+        !typeMap.containsKey(symbol) || typeMap.get(symbol) == dataType,
+        String.format("inconsistent data type for symbol: %s", symbol));
+    this.typeMap.put(symbol, dataType);
   }
 
   public boolean containsTypeInfoOf(String path) {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
index afa7e34806..fd221a0b43 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
@@ -27,7 +27,9 @@ import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.metadata.utils.MetaUtils;
 import org.apache.iotdb.db.mpp.common.MPPQueryContext;
+import org.apache.iotdb.db.mpp.common.header.ColumnHeaderConstant;
 import org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
+import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
 import org.apache.iotdb.db.mpp.plan.analyze.ExpressionAnalyzer;
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
@@ -78,13 +80,17 @@ import org.apache.iotdb.db.mpp.plan.statement.component.SortItem;
 import org.apache.iotdb.db.mpp.plan.statement.component.SortKey;
 import org.apache.iotdb.db.query.aggregation.AggregationType;
 import org.apache.iotdb.db.utils.SchemaUtils;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.filter.basic.Filter;
+import org.apache.iotdb.tsfile.utils.Pair;
 
+import com.google.common.base.Function;
 import org.apache.commons.lang.Validate;
 
 import java.time.ZoneId;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -101,7 +107,10 @@ public class LogicalPlanBuilder {
 
   private final MPPQueryContext context;
 
-  public LogicalPlanBuilder(MPPQueryContext context) {
+  private final Function<Expression, TSDataType> getPreAnalyzedType;
+
+  public LogicalPlanBuilder(Analysis analysis, MPPQueryContext context) {
+    this.getPreAnalyzedType = analysis::getType;
     this.context = context;
   }
 
@@ -114,6 +123,14 @@ public class LogicalPlanBuilder {
     return this;
   }
 
+  private void updateTypeProvider(Collection<Expression> expressions) {
+    expressions.forEach(
+        expression ->
+            context
+                .getTypeProvider()
+                .setType(expression.toString(), getPreAnalyzedType.apply(expression)));
+  }
+
   public LogicalPlanBuilder planRawDataSource(
       Set<Expression> sourceExpressions, Ordering scanOrder, Filter timeFilter) {
     List<PlanNode> sourceNodeList = new ArrayList<>();
@@ -140,6 +157,8 @@ public class LogicalPlanBuilder {
       }
     }
 
+    updateTypeProvider(sourceExpressions);
+
     this.root = convergeWithTimeJoin(sourceNodeList, scanOrder);
     return this;
   }
@@ -160,6 +179,7 @@ public class LogicalPlanBuilder {
         sourceNodeList.add(new LastQueryScanNode(context.getQueryId().genPlanNodeId(), selectPath));
       }
     }
+    updateTypeProvider(sourceExpressions);
 
     this.root =
         new LastQueryNode(
@@ -167,6 +187,12 @@ public class LogicalPlanBuilder {
             sourceNodeList,
             globalTimeFilter,
             mergeOrderParameter);
+    ColumnHeaderConstant.lastQueryColumnHeaders.forEach(
+        columnHeader ->
+            context
+                .getTypeProvider()
+                .setType(columnHeader.getColumnName(), columnHeader.getColumnType()));
+
     return this;
   }
 
@@ -177,9 +203,7 @@ public class LogicalPlanBuilder {
       Filter timeFilter,
       GroupByTimeParameter groupByTimeParameter,
       Set<Expression> aggregationExpressions,
-      Map<Expression, Set<Expression>> groupByLevelExpressions,
-      TypeProvider typeProvider) {
-
+      Map<Expression, Set<Expression>> groupByLevelExpressions) {
     boolean needCheckAscending = groupByTimeParameter == null;
     Map<PartialPath, List<AggregationDescriptor>> ascendingAggregations = new HashMap<>();
     Map<PartialPath, List<AggregationDescriptor>> descendingAggregations = new HashMap<>();
@@ -189,7 +213,6 @@ public class LogicalPlanBuilder {
           curStep,
           scanOrder,
           needCheckAscending,
-          typeProvider,
           ascendingAggregations,
           descendingAggregations);
     }
@@ -201,6 +224,7 @@ public class LogicalPlanBuilder {
             scanOrder,
             timeFilter,
             groupByTimeParameter);
+    updateTypeProvider(sourceExpressions);
 
     return convergeAggregationSource(
         sourceNodeList,
@@ -219,8 +243,7 @@ public class LogicalPlanBuilder {
       GroupByTimeParameter groupByTimeParameter,
       Set<Expression> aggregationExpressions,
       List<Integer> measurementIndexes,
-      Map<Expression, Set<Expression>> groupByLevelExpressions,
-      TypeProvider typeProvider) {
+      Map<Expression, Set<Expression>> groupByLevelExpressions) {
     checkArgument(
         sourceExpressions.size() == measurementIndexes.size(),
         "Each aggregate should correspond to a column of output.");
@@ -238,7 +261,6 @@ public class LogicalPlanBuilder {
               curStep,
               scanOrder,
               needCheckAscending,
-              typeProvider,
               ascendingAggregations,
               descendingAggregations);
       aggregationToMeasurementIndexMap.put(aggregationDescriptor, measurementIndexes.get(index));
@@ -252,6 +274,7 @@ public class LogicalPlanBuilder {
             scanOrder,
             timeFilter,
             groupByTimeParameter);
+    updateTypeProvider(sourceExpressions);
 
     if (!curStep.isOutputPartial()) {
       // update measurementIndexes
@@ -280,14 +303,13 @@ public class LogicalPlanBuilder {
       AggregationStep curStep,
       Ordering scanOrder,
       boolean needCheckAscending,
-      TypeProvider typeProvider,
       Map<PartialPath, List<AggregationDescriptor>> ascendingAggregations,
       Map<PartialPath, List<AggregationDescriptor>> descendingAggregations) {
     AggregationDescriptor aggregationDescriptor =
         new AggregationDescriptor(
             sourceExpression.getFunctionName(), curStep, sourceExpression.getExpressions());
     if (curStep.isOutputPartial()) {
-      updateTypeProviderByPartialAggregation(aggregationDescriptor, typeProvider);
+      updateTypeProviderByPartialAggregation(aggregationDescriptor, context.getTypeProvider());
     }
     PartialPath selectPath =
         ((TimeSeriesOperand) sourceExpression.getExpressions().get(0)).getPath();
@@ -416,9 +438,13 @@ public class LogicalPlanBuilder {
 
   public LogicalPlanBuilder planDeviceView(
       Map<String, PlanNode> deviceNameToSourceNodesMap,
-      List<String> outputColumnNames,
+      List<Pair<Expression, String>> outputExpressions,
       Map<String, List<Integer>> deviceToMeasurementIndexesMap,
       Ordering mergeOrder) {
+    List<String> outputColumnNames =
+        outputExpressions.stream()
+            .map(pair -> pair.getLeft().toString())
+            .collect(Collectors.toList());
     DeviceViewNode deviceViewNode =
         new DeviceViewNode(
             context.getQueryId().genPlanNodeId(),
@@ -434,6 +460,9 @@ public class LogicalPlanBuilder {
       deviceViewNode.addChildDeviceNode(deviceName, subPlan);
     }
 
+    context.getTypeProvider().setType(ColumnHeaderConstant.COLUMN_DEVICE, TSDataType.TEXT);
+    updateTypeProvider(outputExpressions.stream().map(Pair::getLeft).collect(Collectors.toList()));
+
     this.root = deviceViewNode;
     return this;
   }
@@ -461,7 +490,6 @@ public class LogicalPlanBuilder {
       Set<Expression> aggregationExpressions,
       GroupByTimeParameter groupByTimeParameter,
       AggregationStep curStep,
-      TypeProvider typeProvider,
       Ordering scanOrder) {
     if (aggregationExpressions == null) {
       return this;
@@ -469,10 +497,12 @@ public class LogicalPlanBuilder {
 
     List<AggregationDescriptor> aggregationDescriptorList =
         constructAggregationDescriptorList(aggregationExpressions, curStep);
+    updateTypeProvider(aggregationExpressions);
     if (curStep.isOutputPartial()) {
       aggregationDescriptorList.forEach(
           aggregationDescriptor ->
-              updateTypeProviderByPartialAggregation(aggregationDescriptor, typeProvider));
+              updateTypeProviderByPartialAggregation(
+                  aggregationDescriptor, context.getTypeProvider()));
     }
     this.root =
         new AggregationNode(
@@ -533,6 +563,7 @@ public class LogicalPlanBuilder {
                   .collect(Collectors.toList()),
               groupedExpression.getExpressions().get(0)));
     }
+    updateTypeProvider(groupByLevelExpressions.keySet());
     return new GroupByLevelNode(
         context.getQueryId().genPlanNodeId(),
         children,
@@ -605,6 +636,7 @@ public class LogicalPlanBuilder {
             isGroupByTime,
             zoneId,
             scanOrder);
+    updateTypeProvider(selectExpressions);
     return this;
   }
 
@@ -632,6 +664,7 @@ public class LogicalPlanBuilder {
             isGroupByTime,
             zoneId,
             scanOrder);
+    updateTypeProvider(transformExpressions);
     return this;
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
index 87d59a3e2e..d1d5d46e20 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
@@ -69,7 +69,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
-import java.util.stream.Collectors;
 
 /**
  * This visitor is used to generate a logical plan for the statement and returns the {@link
@@ -91,7 +90,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
 
   @Override
   public PlanNode visitQuery(QueryStatement queryStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
 
     if (queryStatement.isLastQuery()) {
       return planBuilder
@@ -105,7 +104,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
     if (queryStatement.isAlignByDevice()) {
       Map<String, PlanNode> deviceToSubPlanMap = new TreeMap<>();
       for (String deviceName : analysis.getDeviceToSourceExpressions().keySet()) {
-        LogicalPlanBuilder subPlanBuilder = new LogicalPlanBuilder(context);
+        LogicalPlanBuilder subPlanBuilder = new LogicalPlanBuilder(analysis, context);
         subPlanBuilder =
             subPlanBuilder.withNewRoot(
                 visitQueryBody(
@@ -129,9 +128,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
       planBuilder =
           planBuilder.planDeviceView(
               deviceToSubPlanMap,
-              analysis.getRespDatasetHeader().getColumnNameWithoutAlias().stream()
-                  .distinct()
-                  .collect(Collectors.toList()),
+              analysis.getOutputExpressions(),
               analysis.getDeviceToMeasurementIndexesMap(),
               queryStatement.getResultTimeOrder());
     } else {
@@ -171,7 +168,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
       Expression havingExpression,
       List<Integer> measurementIndexes, // only used in ALIGN BY DEVICE
       MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
 
     // plan data source node
     if (isRawDataSource) {
@@ -209,7 +206,6 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
                 aggregationExpressions,
                 analysis.getGroupByTimeParameter(),
                 curStep,
-                analysis.getTypeProvider(),
                 queryStatement.getResultTimeOrder());
 
         if (curStep.isOutputPartial()) {
@@ -307,8 +303,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
                 analysis.getGroupByTimeParameter(),
                 aggregationExpressions,
                 measurementIndexes,
-                analysis.getGroupByLevelExpressions(),
-                analysis.getTypeProvider());
+                analysis.getGroupByLevelExpressions());
         if (queryStatement.isGroupByLevel()) {
           planBuilder = // plan Having with GroupByLevel
               planBuilder.planFilterAndTransform(
@@ -335,8 +330,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
                 analysis.getGlobalTimeFilter(),
                 analysis.getGroupByTimeParameter(),
                 aggregationExpressions,
-                analysis.getGroupByLevelExpressions(),
-                analysis.getTypeProvider());
+                analysis.getGroupByLevelExpressions());
 
         if (queryStatement.isGroupByLevel()) {
           planBuilder = // plan Having with GroupByLevel
@@ -483,7 +477,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowTimeSeries(
       ShowTimeSeriesStatement showTimeSeriesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
 
     // If there is only one region, we can push down the offset and limit operation to
     // source operator.
@@ -519,7 +513,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
         && null != analysis.getDataPartitionInfo()
         && 0 != analysis.getDataPartitionInfo().getDataPartitionMap().size()) {
       PlanNode lastPlanNode =
-          new LogicalPlanBuilder(context)
+          new LogicalPlanBuilder(analysis, context)
               .planLast(
                   analysis.getSourceExpressions(),
                   analysis.getGlobalTimeFilter(),
@@ -541,7 +535,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowDevices(
       ShowDevicesStatement showDevicesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
 
     // If there is only one region, we can push down the offset and limit operation to
     // source operator.
@@ -578,7 +572,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitCountDevices(
       CountDevicesStatement countDevicesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
     return planBuilder
         .planDevicesCountSource(
             countDevicesStatement.getPathPattern(), countDevicesStatement.isPrefixPath())
@@ -589,7 +583,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitCountTimeSeries(
       CountTimeSeriesStatement countTimeSeriesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
     return planBuilder
         .planTimeSeriesCountSource(
             countTimeSeriesStatement.getPathPattern(),
@@ -605,7 +599,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitCountLevelTimeSeries(
       CountLevelTimeSeriesStatement countLevelTimeSeriesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
     return planBuilder
         .planLevelTimeSeriesCountSource(
             countLevelTimeSeriesStatement.getPathPattern(),
@@ -620,7 +614,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
 
   @Override
   public PlanNode visitCountNodes(CountNodesStatement countStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
     return planBuilder
         .planNodePathsSchemaSource(countStatement.getPathPattern(), countStatement.getLevel())
         .planSchemaQueryMerge(false)
@@ -710,7 +704,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitSchemaFetch(
       SchemaFetchStatement schemaFetchStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
     List<String> storageGroupList =
         new ArrayList<>(analysis.getSchemaPartitionInfo().getSchemaPartitionMap().keySet());
     return planBuilder
@@ -725,7 +719,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowChildPaths(
       ShowChildPathsStatement showChildPathsStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
     return planBuilder
         .planNodePathsSchemaSource(showChildPathsStatement.getPartialPath(), -1)
         .planSchemaQueryMerge(false)
@@ -736,7 +730,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowChildNodes(
       ShowChildNodesStatement showChildNodesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
     return planBuilder
         .planNodePathsSchemaSource(showChildNodesStatement.getPartialPath(), -1)
         .planSchemaQueryMerge(false)
@@ -768,7 +762,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowPathsUsingTemplate(
       ShowPathsUsingTemplateStatement showPathsUsingTemplateStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
     planBuilder =
         planBuilder
             .planPathsUsingTemplateSource(analysis.getTemplateSetInfo().left.getId())
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java
new file mode 100644
index 0000000000..0c78183794
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java
@@ -0,0 +1,54 @@
+/*
+ * 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.mpp.plan.planner;
+
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.SimplePlanVisitor;
+
+public class SubPlanTypeExtractor {
+
+  public static TypeProvider extractor(PlanNode root, TypeProvider allTypes) {
+    TypeProvider typeProvider = new TypeProvider();
+    root.accept(new Visitor(typeProvider, allTypes), null);
+    return typeProvider;
+  }
+
+  private static class Visitor extends SimplePlanVisitor<Void> {
+
+    private final TypeProvider typeProvider;
+    private final TypeProvider allTypes;
+
+    public Visitor(TypeProvider typeProvider, TypeProvider allTypes) {
+      this.typeProvider = typeProvider;
+      this.allTypes = allTypes;
+    }
+
+    @Override
+    public Void visitPlan(PlanNode node, Void context) {
+      node.getOutputColumnNames()
+          .forEach(name -> typeProvider.setType(name, allTypes.getType(name)));
+      for (PlanNode source : node.getChildren()) {
+        source.accept(this, context);
+      }
+      return null;
+    }
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SimpleFragmentParallelPlanner.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SimpleFragmentParallelPlanner.java
index d5c73f6822..2559f46e4b 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SimpleFragmentParallelPlanner.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SimpleFragmentParallelPlanner.java
@@ -112,7 +112,7 @@ public class SimpleFragmentParallelPlanner implements IFragmentParallelPlaner {
     fragmentInstance.setDataRegionAndHost(regionReplicaSet);
     fragmentInstance.setHostDataNode(selectTargetDataNode(regionReplicaSet));
 
-    fragmentInstance.getFragment().setTypeProvider(analysis.getTypeProvider());
+    fragmentInstance.getFragment().generateTypeProvider(queryContext.getTypeProvider());
     instanceMap.putIfAbsent(fragment.getId(), fragmentInstance);
     fragmentInstanceList.add(fragmentInstance);
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SourceRewriter.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SourceRewriter.java
index b063c4cb62..c608e09e1b 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SourceRewriter.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/distribution/SourceRewriter.java
@@ -315,7 +315,7 @@ public class SourceRewriter extends SimplePlanNodeRewriter<DistributionPlanConte
     leafAggDescriptorList.forEach(
         d ->
             LogicalPlanBuilder.updateTypeProviderByPartialAggregation(
-                d, analysis.getTypeProvider()));
+                d, context.queryContext.getTypeProvider()));
     List<AggregationDescriptor> rootAggDescriptorList = new ArrayList<>();
     node.getAggregationDescriptorList()
         .forEach(
@@ -532,7 +532,7 @@ public class SourceRewriter extends SimplePlanNodeRewriter<DistributionPlanConte
     rootAggDescriptorList.forEach(
         d ->
             LogicalPlanBuilder.updateTypeProviderByPartialAggregation(
-                d, analysis.getTypeProvider()));
+                d, context.queryContext.getTypeProvider()));
     checkArgument(
         sources.size() > 0, "Aggregation sources should not be empty when distribution planning");
     SeriesAggregationSourceNode seed = sources.get(0);
@@ -590,7 +590,7 @@ public class SourceRewriter extends SimplePlanNodeRewriter<DistributionPlanConte
             : groupSourcesForGroupByLevel(root, sourceGroup, context);
 
     // Then, we calculate the attributes for GroupByLevelNode in each level
-    calculateGroupByLevelNodeAttributes(newRoot, 0);
+    calculateGroupByLevelNodeAttributes(newRoot, 0, context);
     return newRoot;
   }
 
@@ -672,11 +672,13 @@ public class SourceRewriter extends SimplePlanNodeRewriter<DistributionPlanConte
   }
 
   // TODO: (xingtanzjr) consider to implement the descriptor construction in every class
-  private void calculateGroupByLevelNodeAttributes(PlanNode node, int level) {
+  private void calculateGroupByLevelNodeAttributes(
+      PlanNode node, int level, DistributionPlanContext context) {
     if (node == null) {
       return;
     }
-    node.getChildren().forEach(child -> calculateGroupByLevelNodeAttributes(child, level + 1));
+    node.getChildren()
+        .forEach(child -> calculateGroupByLevelNodeAttributes(child, level + 1, context));
 
     // Construct all outputColumns from children. Using Set here to avoid duplication
     Set<String> childrenOutputColumns = new HashSet<>();
@@ -697,7 +699,7 @@ public class SourceRewriter extends SimplePlanNodeRewriter<DistributionPlanConte
         if (keep) {
           descriptorList.add(originalDescriptor);
           LogicalPlanBuilder.updateTypeProviderByPartialAggregation(
-              originalDescriptor, analysis.getTypeProvider());
+              originalDescriptor, context.queryContext.getTypeProvider());
         }
       }
       handle.setAggregationDescriptorList(descriptorList);
@@ -730,7 +732,7 @@ public class SourceRewriter extends SimplePlanNodeRewriter<DistributionPlanConte
         descriptor.setInputExpressions(new ArrayList<>(descriptorExpressions));
         descriptorList.add(descriptor);
         LogicalPlanBuilder.updateTypeProviderByPartialAggregation(
-            descriptor, analysis.getTypeProvider());
+            descriptor, context.queryContext.getTypeProvider());
       }
       handle.setGroupByLevelDescriptors(descriptorList);
     }
@@ -779,7 +781,7 @@ public class SourceRewriter extends SimplePlanNodeRewriter<DistributionPlanConte
               d -> {
                 d.setStep(isFinal ? AggregationStep.FINAL : AggregationStep.PARTIAL);
                 LogicalPlanBuilder.updateTypeProviderByPartialAggregation(
-                    d, analysis.getTypeProvider());
+                    d, context.queryContext.getTypeProvider());
               });
     }
     return sources;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/PlanFragment.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/PlanFragment.java
index 000d94e9eb..c21cfa28fc 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/PlanFragment.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/PlanFragment.java
@@ -22,6 +22,7 @@ import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
 import org.apache.iotdb.commons.partition.DataPartition;
 import org.apache.iotdb.db.mpp.common.PlanFragmentId;
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.mpp.plan.planner.SubPlanTypeExtractor;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.IPartitionRelatedNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
@@ -36,8 +37,10 @@ import java.util.Objects;
 /** PlanFragment contains a sub-query of distributed query. */
 public class PlanFragment {
   // TODO once you add field for this class you need to change the serialize and deserialize methods
-  private PlanFragmentId id;
+  private final PlanFragmentId id;
   private PlanNode planNodeTree;
+
+  // map from output column name (for every node) to its datatype
   private TypeProvider typeProvider;
 
   // indicate whether this PlanFragment is the root of the whole Fragment-Plan-Tree or not
@@ -69,6 +72,10 @@ public class PlanFragment {
     this.typeProvider = typeProvider;
   }
 
+  public void generateTypeProvider(TypeProvider allTypes) {
+    this.typeProvider = SubPlanTypeExtractor.extractor(planNodeTree, allTypes);
+  }
+
   public boolean isRoot() {
     return isRoot;
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/SimplePlanVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/SimplePlanVisitor.java
new file mode 100644
index 0000000000..7b26611ee4
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/SimplePlanVisitor.java
@@ -0,0 +1,30 @@
+/*
+ * 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.mpp.plan.planner.plan.node;
+
+public class SimplePlanVisitor<C> extends PlanVisitor<Void, C> {
+  @Override
+  public Void visitPlan(PlanNode node, C context) {
+    for (PlanNode source : node.getChildren()) {
+      source.accept(this, context);
+    }
+    return null;
+  }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java
index b150d8d6f8..9361038cae 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java
@@ -21,12 +21,10 @@ package org.apache.iotdb.db.mpp.plan.plan.distribution;
 
 import org.apache.iotdb.common.rpc.thrift.TEndPoint;
 import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.mpp.common.MPPQueryContext;
 import org.apache.iotdb.db.mpp.common.QueryId;
-import org.apache.iotdb.db.mpp.plan.expression.Expression;
-import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
-import org.apache.iotdb.db.mpp.plan.planner.LogicalPlanBuilder;
 import org.apache.iotdb.db.mpp.plan.planner.distribution.DistributionPlanner;
 import org.apache.iotdb.db.mpp.plan.planner.plan.DistributedQueryPlan;
 import org.apache.iotdb.db.mpp.plan.planner.plan.LogicalQueryPlan;
@@ -35,16 +33,17 @@ import org.apache.iotdb.db.mpp.plan.planner.plan.node.process.ExchangeNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.process.last.LastQueryCollectNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.process.last.LastQueryMergeNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.process.last.LastQueryNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.source.AlignedLastQueryScanNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.source.LastQueryScanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.OrderByParameter;
 
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 public class LastQueryTest {
 
@@ -197,12 +196,21 @@ public class LastQueryTest {
 
   private LogicalQueryPlan constructLastQuery(List<String> paths, MPPQueryContext context)
       throws IllegalPathException {
-    LogicalPlanBuilder builder = new LogicalPlanBuilder(context);
-    Set<Expression> expressions = new HashSet<>();
+    List<PlanNode> sourceNodeList = new ArrayList<>();
     for (String path : paths) {
-      expressions.add(new TimeSeriesOperand(new MeasurementPath(path)));
+      MeasurementPath selectPath = new MeasurementPath(path);
+      if (selectPath.isUnderAlignedEntity()) {
+        sourceNodeList.add(
+            new AlignedLastQueryScanNode(
+                context.getQueryId().genPlanNodeId(), new AlignedPath(selectPath)));
+      } else {
+        sourceNodeList.add(new LastQueryScanNode(context.getQueryId().genPlanNodeId(), selectPath));
+      }
     }
-    PlanNode root = builder.planLast(expressions, null, new OrderByParameter()).getRoot();
+
+    PlanNode root =
+        new LastQueryNode(
+            context.getQueryId().genPlanNodeId(), sourceNodeList, null, new OrderByParameter());
     return new LogicalQueryPlan(context, root);
   }
 }


[iotdb] 03/07: add SymbolAllocator

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

hui pushed a commit to branch lmh/TypeProviderOpt
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 000c970689e18652ebf635918bf083d1d5009e42
Author: Minghui Liu <li...@foxmail.com>
AuthorDate: Tue Sep 6 15:51:59 2022 +0800

    add SymbolAllocator
---
 .../apache/iotdb/db/mpp/plan/analyze/Analysis.java |   4 -
 .../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java  | 137 ++++++++-------------
 .../apache/iotdb/db/mpp/plan/analyze/Analyzer.java |   5 +-
 .../db/mpp/plan/analyze/ExpressionAnalyzer.java    | 118 +++---------------
 .../mpp/plan/analyze/GroupByLevelController.java   |   4 +-
 .../db/mpp/plan/planner/LogicalPlanBuilder.java    |   5 +-
 .../db/mpp/plan/planner/LogicalPlanVisitor.java    |  29 ++---
 .../apache/iotdb/db/mpp/plan/planner/Symbol.java   |  29 +++++
 .../iotdb/db/mpp/plan/planner/SymbolAllocator.java |  66 ++++++++++
 .../mpp/plan/plan/distribution/LastQueryTest.java  |   3 +-
 10 files changed, 186 insertions(+), 214 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
index 2e61ba99e5..c106572837 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
@@ -227,10 +227,6 @@ public class Analysis {
     return typeProvider;
   }
 
-  public void setTypeProvider(TypeProvider typeProvider) {
-    this.typeProvider = typeProvider;
-  }
-
   public TSDataType getType(Expression expression) {
     TSDataType type = expressionTypes.get(NodeRef.of(expression));
     checkArgument(type != null, "Expression not analyzed: %s", expression);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
index db93582836..a3f6cee2de 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
@@ -128,18 +128,13 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
 
   private final IPartitionFetcher partitionFetcher;
   private final ISchemaFetcher schemaFetcher;
-  private final TypeProvider typeProvider;
   private final MPPQueryContext context;
 
   public AnalyzeVisitor(
-      IPartitionFetcher partitionFetcher,
-      ISchemaFetcher schemaFetcher,
-      TypeProvider typeProvider,
-      MPPQueryContext context) {
+      IPartitionFetcher partitionFetcher, ISchemaFetcher schemaFetcher, MPPQueryContext context) {
     this.context = context;
     this.partitionFetcher = partitionFetcher;
     this.schemaFetcher = schemaFetcher;
-    this.typeProvider = typeProvider;
   }
 
   private String getLogHeader() {
@@ -237,7 +232,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
         Map<String, Set<String>> deviceToMeasurementsMap = new HashMap<>();
         outputExpressions =
             analyzeSelect(
-                queryStatement,
+                analysis,
                 schemaTree,
                 deviceList,
                 deviceToTransformExpressions,
@@ -249,14 +244,12 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
             try {
               deviceToTransformExpressionsInHaving.put(
                   device.toString(),
-                  ExpressionAnalyzer.removeWildcardInFilterByDevice(
+                  new HashSet<>(
+                      ExpressionAnalyzer.removeWildcardInFilterByDevice(
                           queryStatement.getHavingCondition().getPredicate(),
                           device,
                           schemaTree,
-                          typeProvider,
-                          false)
-                      .stream()
-                      .collect(Collectors.toSet()));
+                          false)));
             } catch (SemanticException e) {
               if (e instanceof MeasurementNotExistException) {
                 logger.warn(e.getMessage());
@@ -328,8 +321,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
               havingExpression =
                   analyzeHavingSplitByDevice(
                       transformExpressionsInHaving); // construct Filter from Having
-
-              havingExpression.inferTypes(typeProvider);
+              analyzeExpression(analysis, havingExpression);
               deviceToHavingExpression.put(deviceName, havingExpression);
             }
 
@@ -385,7 +377,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
               throw e;
             }
             deviceToQueryFilter.put(devicePath.getFullPath(), queryFilter);
-            queryFilter.inferTypes(typeProvider);
+            analyzeExpression(analysis, queryFilter);
             updateSource(
                 queryFilter,
                 deviceToSourceExpressions.computeIfAbsent(
@@ -397,7 +389,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
         analysis.setDeviceToSourceExpressions(deviceToSourceExpressions);
         analysis.setDeviceToTransformExpressions(deviceToTransformExpressions);
       } else {
-        outputExpressions = analyzeSelect(queryStatement, schemaTree);
+        outputExpressions = analyzeSelect(analysis, schemaTree);
         Set<Expression> transformExpressions =
             outputExpressions.stream()
                 .map(Pair::getLeft)
@@ -407,14 +399,12 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
         // used to analyzeAggregation in Having expression and updateSource
         Set<Expression> transformExpressionsInHaving =
             queryStatement.hasHaving()
-                ? ExpressionAnalyzer.removeWildcardInFilter(
+                ? new HashSet<>(
+                    ExpressionAnalyzer.removeWildcardInFilter(
                         queryStatement.getHavingCondition().getPredicate(),
                         queryStatement.getFromComponent().getPrefixPaths(),
                         schemaTree,
-                        typeProvider,
-                        false)
-                    .stream()
-                    .collect(Collectors.toSet())
+                        false))
                 : null;
 
         if (queryStatement.isGroupByLevel()) {
@@ -422,7 +412,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
           Map<Expression, Expression> rawPathToGroupedPathMap = new HashMap<>();
           Map<Expression, Set<Expression>> groupByLevelExpressions =
               analyzeGroupByLevel(
-                  queryStatement, outputExpressions, transformExpressions, rawPathToGroupedPathMap);
+                  analysis, outputExpressions, transformExpressions, rawPathToGroupedPathMap);
           analysis.setGroupByLevelExpressions(groupByLevelExpressions);
           analysis.setRawPathToGroupedPathMap(rawPathToGroupedPathMap);
         }
@@ -452,7 +442,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
                     analysis.getGroupByLevelExpressions(),
                     transformExpressionsInHaving,
                     aggregationExpressionsInHaving);
-            havingExpression.inferTypes(typeProvider);
+            analyzeExpression(analysis, havingExpression);
             analysis.setHavingExpression(havingExpression);
           }
           analysis.setAggregationExpressions(aggregationExpressions);
@@ -480,7 +470,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
           Expression queryFilter = analyzeWhere(queryStatement, schemaTree);
 
           // update sourceExpression according to queryFilter
-          queryFilter.inferTypes(typeProvider);
+          analyzeExpression(analysis, queryFilter);
           updateSource(queryFilter, sourceExpressions, isRawDataSource);
           analysis.setQueryFilter(queryFilter);
         }
@@ -501,16 +491,13 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
 
       if (queryStatement.getFillComponent() != null) {
         FillComponent fillComponent = queryStatement.getFillComponent();
-        List<Expression> fillColumnList =
-            outputExpressions.stream().map(Pair::getLeft).distinct().collect(Collectors.toList());
         analysis.setFillDescriptor(
             new FillDescriptor(fillComponent.getFillPolicy(), fillComponent.getFillValue()));
       }
 
       // generate result set header according to output expressions
-      DatasetHeader datasetHeader = analyzeOutput(queryStatement, outputExpressions);
+      DatasetHeader datasetHeader = analyzeOutput(analysis, outputExpressions);
       analysis.setRespDatasetHeader(datasetHeader);
-      analysis.setTypeProvider(typeProvider);
 
       // fetch partition information
       Set<String> deviceSet = new HashSet<>();
@@ -531,8 +518,8 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
     return analysis;
   }
 
-  private List<Pair<Expression, String>> analyzeSelect(
-      QueryStatement queryStatement, ISchemaTree schemaTree) {
+  private List<Pair<Expression, String>> analyzeSelect(Analysis analysis, ISchemaTree schemaTree) {
+    QueryStatement queryStatement = (QueryStatement) analysis.getStatement();
     List<Pair<Expression, String>> outputExpressions = new ArrayList<>();
     boolean isGroupByLevel = queryStatement.isGroupByLevel();
     ColumnPaginationController paginationController =
@@ -557,8 +544,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
         }
         if (paginationController.hasCurLimit()) {
           if (isGroupByLevel) {
-            ExpressionAnalyzer.updateTypeProvider(expression, typeProvider);
-            expression.inferTypes(typeProvider);
+            analyzeExpression(analysis, expression);
             outputExpressions.add(new Pair<>(expression, resultColumn.getAlias()));
             if (resultColumn.getExpression() instanceof FunctionExpression) {
               queryStatement
@@ -573,9 +559,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
                     ? expression.getExpressionString()
                     : null;
             alias = hasAlias ? resultColumn.getAlias() : alias;
-
-            ExpressionAnalyzer.updateTypeProvider(expressionWithoutAlias, typeProvider);
-            expressionWithoutAlias.inferTypes(typeProvider);
+            analyzeExpression(analysis, expressionWithoutAlias);
             outputExpressions.add(new Pair<>(expressionWithoutAlias, alias));
           }
           paginationController.consumeLimit();
@@ -603,11 +587,12 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
   }
 
   private List<Pair<Expression, String>> analyzeSelect(
-      QueryStatement queryStatement,
+      Analysis analysis,
       ISchemaTree schemaTree,
       Set<PartialPath> deviceList,
       Map<String, Set<Expression>> deviceToTransformExpressions,
       Map<String, Set<String>> deviceToMeasurementsMap) {
+    QueryStatement queryStatement = (QueryStatement) analysis.getStatement();
     List<Pair<Expression, String>> outputExpressions = new ArrayList<>();
     ColumnPaginationController paginationController =
         new ColumnPaginationController(
@@ -623,8 +608,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
           new LinkedHashMap<>();
       for (PartialPath device : deviceList) {
         List<Expression> transformExpressions =
-            ExpressionAnalyzer.concatDeviceAndRemoveWildcard(
-                selectExpression, device, schemaTree, typeProvider);
+            ExpressionAnalyzer.concatDeviceAndRemoveWildcard(selectExpression, device, schemaTree);
         for (Expression transformExpression : transformExpressions) {
           measurementToDeviceTransformExpressions
               .computeIfAbsent(
@@ -652,12 +636,12 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
               measurementToDeviceTransformExpressions.get(measurementExpression);
           deviceToTransformExpressionOfOneMeasurement
               .values()
-              .forEach(expression -> expression.inferTypes(typeProvider));
+              .forEach(expression -> analyzeExpression(analysis, expression));
           // check whether the datatype of paths which has the same measurement name are
           // consistent
           // if not, throw a SemanticException
           checkDataTypeConsistencyInAlignByDevice(
-              new ArrayList<>(deviceToTransformExpressionOfOneMeasurement.values()));
+              analysis, new ArrayList<>(deviceToTransformExpressionOfOneMeasurement.values()));
 
           // add outputExpressions
           Expression measurementExpressionWithoutAlias =
@@ -667,16 +651,13 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
                   ? measurementExpression.getExpressionString()
                   : null;
           alias = hasAlias ? resultColumn.getAlias() : alias;
-          ExpressionAnalyzer.updateTypeProvider(measurementExpressionWithoutAlias, typeProvider);
-          measurementExpressionWithoutAlias.inferTypes(typeProvider);
+          analyzeExpression(analysis, measurementExpressionWithoutAlias);
           outputExpressions.add(new Pair<>(measurementExpressionWithoutAlias, alias));
 
           // add deviceToTransformExpressions
           for (String deviceName : deviceToTransformExpressionOfOneMeasurement.keySet()) {
             Expression transformExpression =
                 deviceToTransformExpressionOfOneMeasurement.get(deviceName);
-            ExpressionAnalyzer.updateTypeProvider(transformExpression, typeProvider);
-            transformExpression.inferTypes(typeProvider);
             deviceToTransformExpressions
                 .computeIfAbsent(deviceName, key -> new LinkedHashSet<>())
                 .add(ExpressionAnalyzer.removeAliasFromExpression(transformExpression));
@@ -720,7 +701,6 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
       if (globalTimeFilter == null) {
         globalTimeFilter = groupByFilter;
       } else {
-        // TODO: optimize the filter
         globalTimeFilter = FilterFactory.and(globalTimeFilter, groupByFilter);
       }
     }
@@ -788,7 +768,6 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
             queryStatement.getWhereCondition().getPredicate(),
             queryStatement.getFromComponent().getPrefixPaths(),
             schemaTree,
-            typeProvider,
             true);
     return ExpressionUtils.constructQueryFilter(
         rewrittenPredicates.stream().distinct().collect(Collectors.toList()));
@@ -798,11 +777,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
       QueryStatement queryStatement, PartialPath devicePath, ISchemaTree schemaTree) {
     List<Expression> rewrittenPredicates =
         ExpressionAnalyzer.removeWildcardInFilterByDevice(
-            queryStatement.getWhereCondition().getPredicate(),
-            devicePath,
-            schemaTree,
-            typeProvider,
-            true);
+            queryStatement.getWhereCondition().getPredicate(), devicePath, schemaTree, true);
     return ExpressionUtils.constructQueryFilter(
         rewrittenPredicates.stream().distinct().collect(Collectors.toList()));
   }
@@ -841,8 +816,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
       List<Expression> inputExpressions,
       Map<Expression, Set<Expression>> groupByLevelExpressions) {
     GroupByLevelController groupByLevelController =
-        new GroupByLevelController(
-            queryStatement.getGroupByLevelComponent().getLevels(), typeProvider);
+        new GroupByLevelController(queryStatement.getGroupByLevelComponent().getLevels());
     for (Expression inputExpression : inputExpressions) {
       groupByLevelController.control(false, inputExpression, null);
     }
@@ -852,18 +826,18 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
   }
 
   private Map<Expression, Set<Expression>> analyzeGroupByLevel(
-      QueryStatement queryStatement,
+      Analysis analysis,
       List<Pair<Expression, String>> outputExpressions,
       Set<Expression> transformExpressions,
       Map<Expression, Expression> rawPathToGroupedPathMap) {
+    QueryStatement queryStatement = (QueryStatement) analysis.getStatement();
     GroupByLevelController groupByLevelController =
-        new GroupByLevelController(
-            queryStatement.getGroupByLevelComponent().getLevels(), typeProvider);
+        new GroupByLevelController(queryStatement.getGroupByLevelComponent().getLevels());
     for (int i = 0; i < outputExpressions.size(); i++) {
-      Pair<Expression, String> measurementWithAlias = outputExpressions.get(i);
+      Pair<Expression, String> expressionAliasPair = outputExpressions.get(i);
       boolean isCountStar = queryStatement.getGroupByLevelComponent().isCountStar(i);
       groupByLevelController.control(
-          isCountStar, measurementWithAlias.left, measurementWithAlias.right);
+          isCountStar, expressionAliasPair.left, expressionAliasPair.right);
     }
     Map<Expression, Set<Expression>> rawGroupByLevelExpressions =
         groupByLevelController.getGroupedPathMap();
@@ -887,27 +861,16 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
         Expression groupedExpressionWithoutAlias = outputExpression.left;
 
         Set<Expression> rawExpressions = rawGroupByLevelExpressions.get(groupedExpression);
-        rawExpressions.forEach(
-            expression -> ExpressionAnalyzer.updateTypeProvider(expression, typeProvider));
-        rawExpressions.forEach(expression -> expression.inferTypes(typeProvider));
+        rawExpressions.forEach(expression -> analyzeExpression(analysis, expression));
 
         Set<Expression> rawExpressionsWithoutAlias =
             rawExpressions.stream()
                 .map(ExpressionAnalyzer::removeAliasFromExpression)
                 .collect(Collectors.toSet());
-        rawExpressionsWithoutAlias.forEach(
-            expression -> ExpressionAnalyzer.updateTypeProvider(expression, typeProvider));
-        rawExpressionsWithoutAlias.forEach(expression -> expression.inferTypes(typeProvider));
+        rawExpressionsWithoutAlias.forEach(expression -> analyzeExpression(analysis, expression));
 
         groupByLevelExpressions.put(groupedExpressionWithoutAlias, rawExpressionsWithoutAlias);
-
-        TSDataType dataType =
-            typeProvider.getType(
-                new ArrayList<>(groupByLevelExpressions.get(groupedExpressionWithoutAlias))
-                    .get(0)
-                    .getExpressionString());
-        typeProvider.setType(groupedExpression.getExpressionString(), dataType);
-        typeProvider.setType(groupedExpressionWithoutAlias.getExpressionString(), dataType);
+        analyzeExpression(analysis, groupedExpressionWithoutAlias);
         outputExpressions.add(outputExpression);
         paginationController.consumeLimit();
       } else {
@@ -934,22 +897,23 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
   }
 
   private DatasetHeader analyzeOutput(
-      QueryStatement queryStatement, List<Pair<Expression, String>> outputExpressions) {
+      Analysis analysis, List<Pair<Expression, String>> outputExpressions) {
+    QueryStatement queryStatement = (QueryStatement) analysis.getStatement();
     boolean isIgnoreTimestamp =
         queryStatement.isAggregationQuery() && !queryStatement.isGroupByTime();
     List<ColumnHeader> columnHeaders = new ArrayList<>();
     if (queryStatement.isAlignByDevice()) {
       columnHeaders.add(
           new ColumnHeader(ColumnHeaderConstant.COLUMN_DEVICE, TSDataType.TEXT, null));
-      typeProvider.setType(ColumnHeaderConstant.COLUMN_DEVICE, TSDataType.TEXT);
     }
     columnHeaders.addAll(
         outputExpressions.stream()
             .map(
-                expressionWithAlias -> {
-                  String columnName = expressionWithAlias.left.getExpressionString();
-                  String alias = expressionWithAlias.right;
-                  return new ColumnHeader(columnName, typeProvider.getType(columnName), alias);
+                expressionAliasPair -> {
+                  String columnName = expressionAliasPair.left.getExpressionString();
+                  String alias = expressionAliasPair.right;
+                  return new ColumnHeader(
+                      columnName, analysis.getType(expressionAliasPair.left), alias);
                 })
             .collect(Collectors.toList()));
     return new DatasetHeader(columnHeaders, isIgnoreTimestamp);
@@ -980,14 +944,10 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
               .collect(Collectors.toCollection(LinkedHashSet::new));
     }
 
-    sourceExpressions.forEach(
-        expression -> ExpressionAnalyzer.updateTypeProvider(expression, typeProvider));
+    sourceExpressions.forEach(expression -> analyzeExpression(analysis, expression));
     analysis.setSourceExpressions(sourceExpressions);
 
     analysis.setRespDatasetHeader(DatasetHeaderFactory.getLastQueryHeader());
-    typeProvider.setType(ColumnHeaderConstant.COLUMN_TIMESERIES, TSDataType.TEXT);
-    typeProvider.setType(ColumnHeaderConstant.COLUMN_VALUE, TSDataType.TEXT);
-    typeProvider.setType(ColumnHeaderConstant.COLUMN_TIMESERIES_DATATYPE, TSDataType.TEXT);
 
     Set<String> deviceSet =
         allSelectedPath.stream().map(MeasurementPath::getDevice).collect(Collectors.toSet());
@@ -1021,16 +981,21 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
     return new OrderByParameter(queryStatement.getSortItemList());
   }
 
+  private void analyzeExpression(Analysis analysis, Expression expression) {
+    ExpressionTypeAnalyzer.analyzeExpression(analysis, expression);
+  }
+
   /**
    * Check datatype consistency in ALIGN BY DEVICE.
    *
    * <p>an inconsistent example: select s0 from root.sg1.d1, root.sg1.d2 align by device, return
    * false while root.sg1.d1.s0 is INT32 and root.sg1.d2.s0 is FLOAT.
    */
-  private void checkDataTypeConsistencyInAlignByDevice(List<Expression> expressions) {
-    TSDataType checkedDataType = typeProvider.getType(expressions.get(0).getExpressionString());
+  private void checkDataTypeConsistencyInAlignByDevice(
+      Analysis analysis, List<Expression> expressions) {
+    TSDataType checkedDataType = analysis.getType(expressions.get(0));
     for (Expression expression : expressions) {
-      if (typeProvider.getType(expression.getExpressionString()) != checkedDataType) {
+      if (analysis.getType(expression) != checkedDataType) {
         throw new SemanticException(
             "ALIGN BY DEVICE: the data types of the same measurement column should be the same across devices.");
       }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analyzer.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analyzer.java
index 6243a1cbb7..567030ff51 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analyzer.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analyzer.java
@@ -33,18 +33,15 @@ public class Analyzer {
 
   private final IPartitionFetcher partitionFetcher;
   private final ISchemaFetcher schemaFetcher;
-  private final TypeProvider typeProvider;
 
   public Analyzer(
       MPPQueryContext context, IPartitionFetcher partitionFetcher, ISchemaFetcher schemaFetcher) {
     this.context = context;
     this.partitionFetcher = partitionFetcher;
     this.schemaFetcher = schemaFetcher;
-    this.typeProvider = new TypeProvider();
   }
 
   public Analysis analyze(Statement statement) {
-    return new AnalyzeVisitor(partitionFetcher, schemaFetcher, typeProvider, context)
-        .process(statement, context);
+    return new AnalyzeVisitor(partitionFetcher, schemaFetcher, context).process(statement, context);
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java
index f330ed9884..491d78aba9 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java
@@ -490,7 +490,6 @@ public class ExpressionAnalyzer {
       Expression predicate,
       List<PartialPath> prefixPaths,
       ISchemaTree schemaTree,
-      TypeProvider typeProvider,
       boolean isWhere) {
     if (predicate instanceof TernaryExpression) {
       List<Expression> firstExpressions =
@@ -498,38 +497,30 @@ public class ExpressionAnalyzer {
               ((TernaryExpression) predicate).getFirstExpression(),
               prefixPaths,
               schemaTree,
-              typeProvider,
               isWhere);
       List<Expression> secondExpressions =
           removeWildcardInFilter(
               ((TernaryExpression) predicate).getSecondExpression(),
               prefixPaths,
               schemaTree,
-              typeProvider,
               isWhere);
       List<Expression> thirdExpressions =
           removeWildcardInFilter(
               ((TernaryExpression) predicate).getThirdExpression(),
               prefixPaths,
               schemaTree,
-              typeProvider,
               isWhere);
       return reconstructTernaryExpressions(
           predicate, firstExpressions, secondExpressions, thirdExpressions);
     } else if (predicate instanceof BinaryExpression) {
       List<Expression> leftExpressions =
           removeWildcardInFilter(
-              ((BinaryExpression) predicate).getLeftExpression(),
-              prefixPaths,
-              schemaTree,
-              typeProvider,
-              isWhere);
+              ((BinaryExpression) predicate).getLeftExpression(), prefixPaths, schemaTree, isWhere);
       List<Expression> rightExpressions =
           removeWildcardInFilter(
               ((BinaryExpression) predicate).getRightExpression(),
               prefixPaths,
               schemaTree,
-              typeProvider,
               isWhere);
       if (predicate.getExpressionType() == ExpressionType.LOGIC_AND) {
         List<Expression> resultExpressions = new ArrayList<>(leftExpressions);
@@ -541,11 +532,7 @@ public class ExpressionAnalyzer {
     } else if (predicate instanceof UnaryExpression) {
       List<Expression> childExpressions =
           removeWildcardInFilter(
-              ((UnaryExpression) predicate).getExpression(),
-              prefixPaths,
-              schemaTree,
-              typeProvider,
-              isWhere);
+              ((UnaryExpression) predicate).getExpression(), prefixPaths, schemaTree, isWhere);
       return reconstructUnaryExpressions((UnaryExpression) predicate, childExpressions);
     } else if (predicate instanceof FunctionExpression) {
       if (predicate.isBuiltInAggregationFunctionExpression() && isWhere) {
@@ -554,8 +541,7 @@ public class ExpressionAnalyzer {
       List<List<Expression>> extendedExpressions = new ArrayList<>();
       for (Expression suffixExpression : predicate.getExpressions()) {
         extendedExpressions.add(
-            removeWildcardInFilter(
-                suffixExpression, prefixPaths, schemaTree, typeProvider, isWhere));
+            removeWildcardInFilter(suffixExpression, prefixPaths, schemaTree, isWhere));
       }
       List<List<Expression>> childExpressionsList = new ArrayList<>();
       cartesianProduct(extendedExpressions, childExpressionsList, 0, new ArrayList<>());
@@ -581,7 +567,6 @@ public class ExpressionAnalyzer {
         }
         noStarPaths.addAll(actualPaths);
       }
-      noStarPaths.forEach(path -> typeProvider.setType(path.getFullPath(), path.getSeriesType()));
       return reconstructTimeSeriesOperands(noStarPaths);
     } else if (predicate instanceof TimestampOperand) {
       // do nothing in the case of "where time > 5"
@@ -654,56 +639,38 @@ public class ExpressionAnalyzer {
    * @return expression list with full path and after binding schema
    */
   public static List<Expression> concatDeviceAndRemoveWildcard(
-      Expression expression,
-      PartialPath devicePath,
-      ISchemaTree schemaTree,
-      TypeProvider typeProvider) {
+      Expression expression, PartialPath devicePath, ISchemaTree schemaTree) {
     if (expression instanceof TernaryExpression) {
       List<Expression> firstExpressions =
           concatDeviceAndRemoveWildcard(
-              ((TernaryExpression) expression).getFirstExpression(),
-              devicePath,
-              schemaTree,
-              typeProvider);
+              ((TernaryExpression) expression).getFirstExpression(), devicePath, schemaTree);
       List<Expression> secondExpressions =
           concatDeviceAndRemoveWildcard(
-              ((TernaryExpression) expression).getSecondExpression(),
-              devicePath,
-              schemaTree,
-              typeProvider);
+              ((TernaryExpression) expression).getSecondExpression(), devicePath, schemaTree);
       List<Expression> thirdExpressions =
           concatDeviceAndRemoveWildcard(
-              ((TernaryExpression) expression).getThirdExpression(),
-              devicePath,
-              schemaTree,
-              typeProvider);
+              ((TernaryExpression) expression).getThirdExpression(), devicePath, schemaTree);
       return reconstructTernaryExpressions(
           expression, firstExpressions, secondExpressions, thirdExpressions);
     } else if (expression instanceof BinaryExpression) {
       List<Expression> leftExpressions =
           concatDeviceAndRemoveWildcard(
-              ((BinaryExpression) expression).getLeftExpression(),
-              devicePath,
-              schemaTree,
-              typeProvider);
+              ((BinaryExpression) expression).getLeftExpression(), devicePath, schemaTree);
       List<Expression> rightExpressions =
           concatDeviceAndRemoveWildcard(
-              ((BinaryExpression) expression).getRightExpression(),
-              devicePath,
-              schemaTree,
-              typeProvider);
+              ((BinaryExpression) expression).getRightExpression(), devicePath, schemaTree);
       return reconstructBinaryExpressions(
           expression.getExpressionType(), leftExpressions, rightExpressions);
     } else if (expression instanceof UnaryExpression) {
       List<Expression> childExpressions =
           concatDeviceAndRemoveWildcard(
-              ((UnaryExpression) expression).getExpression(), devicePath, schemaTree, typeProvider);
+              ((UnaryExpression) expression).getExpression(), devicePath, schemaTree);
       return reconstructUnaryExpressions((UnaryExpression) expression, childExpressions);
     } else if (expression instanceof FunctionExpression) {
       List<List<Expression>> extendedExpressions = new ArrayList<>();
       for (Expression suffixExpression : expression.getExpressions()) {
         List<Expression> concatedExpression =
-            concatDeviceAndRemoveWildcard(suffixExpression, devicePath, schemaTree, typeProvider);
+            concatDeviceAndRemoveWildcard(suffixExpression, devicePath, schemaTree);
         if (concatedExpression != null && concatedExpression.size() != 0) {
           extendedExpressions.add(concatedExpression);
         }
@@ -720,7 +687,6 @@ public class ExpressionAnalyzer {
         return new ArrayList<>();
       }
       List<PartialPath> noStarPaths = new ArrayList<>(actualPaths);
-      noStarPaths.forEach(path -> typeProvider.setType(path.getFullPath(), path.getSeriesType()));
       return reconstructTimeSeriesOperands(noStarPaths);
     } else if (expression instanceof TimestampOperand) {
       // do nothing in the case of "where time > 5"
@@ -740,50 +706,35 @@ public class ExpressionAnalyzer {
    * @return the expression list with full path and after binding schema
    */
   public static List<Expression> removeWildcardInFilterByDevice(
-      Expression predicate,
-      PartialPath devicePath,
-      ISchemaTree schemaTree,
-      TypeProvider typeProvider,
-      boolean isWhere) {
+      Expression predicate, PartialPath devicePath, ISchemaTree schemaTree, boolean isWhere) {
     if (predicate instanceof TernaryExpression) {
       List<Expression> firstExpressions =
           removeWildcardInFilterByDevice(
               ((TernaryExpression) predicate).getFirstExpression(),
               devicePath,
               schemaTree,
-              typeProvider,
               isWhere);
       List<Expression> secondExpressions =
           removeWildcardInFilterByDevice(
               ((TernaryExpression) predicate).getSecondExpression(),
               devicePath,
               schemaTree,
-              typeProvider,
               isWhere);
       List<Expression> thirdExpressions =
           removeWildcardInFilterByDevice(
               ((TernaryExpression) predicate).getThirdExpression(),
               devicePath,
               schemaTree,
-              typeProvider,
               isWhere);
       return reconstructTernaryExpressions(
           predicate, firstExpressions, secondExpressions, thirdExpressions);
     } else if (predicate instanceof BinaryExpression) {
       List<Expression> leftExpressions =
           removeWildcardInFilterByDevice(
-              ((BinaryExpression) predicate).getLeftExpression(),
-              devicePath,
-              schemaTree,
-              typeProvider,
-              isWhere);
+              ((BinaryExpression) predicate).getLeftExpression(), devicePath, schemaTree, isWhere);
       List<Expression> rightExpressions =
           removeWildcardInFilterByDevice(
-              ((BinaryExpression) predicate).getRightExpression(),
-              devicePath,
-              schemaTree,
-              typeProvider,
-              isWhere);
+              ((BinaryExpression) predicate).getRightExpression(), devicePath, schemaTree, isWhere);
       if (predicate.getExpressionType() == ExpressionType.LOGIC_AND) {
         List<Expression> resultExpressions = new ArrayList<>(leftExpressions);
         resultExpressions.addAll(rightExpressions);
@@ -794,11 +745,7 @@ public class ExpressionAnalyzer {
     } else if (predicate instanceof UnaryExpression) {
       List<Expression> childExpressions =
           removeWildcardInFilterByDevice(
-              ((UnaryExpression) predicate).getExpression(),
-              devicePath,
-              schemaTree,
-              typeProvider,
-              isWhere);
+              ((UnaryExpression) predicate).getExpression(), devicePath, schemaTree, isWhere);
       return reconstructUnaryExpressions((UnaryExpression) predicate, childExpressions);
     } else if (predicate instanceof FunctionExpression) {
       if (predicate.isBuiltInAggregationFunctionExpression() && isWhere) {
@@ -807,8 +754,7 @@ public class ExpressionAnalyzer {
       List<List<Expression>> extendedExpressions = new ArrayList<>();
       for (Expression suffixExpression : predicate.getExpressions()) {
         extendedExpressions.add(
-            removeWildcardInFilterByDevice(
-                suffixExpression, devicePath, schemaTree, typeProvider, isWhere));
+            removeWildcardInFilterByDevice(suffixExpression, devicePath, schemaTree, isWhere));
       }
       List<List<Expression>> childExpressionsList = new ArrayList<>();
       cartesianProduct(extendedExpressions, childExpressionsList, 0, new ArrayList<>());
@@ -824,8 +770,6 @@ public class ExpressionAnalyzer {
                 "ALIGN BY DEVICE: Measurement '%s' does not exist in device '%s'",
                 measurement, devicePath));
       }
-
-      noStarPaths.forEach(path -> typeProvider.setType(path.getFullPath(), path.getSeriesType()));
       return reconstructTimeSeriesOperands(noStarPaths);
     } else if (predicate instanceof TimestampOperand) {
       // do nothing in the case of "where time > 5"
@@ -1062,36 +1006,6 @@ public class ExpressionAnalyzer {
     }
   }
 
-  /** Update typeProvider by expression. */
-  public static void updateTypeProvider(Expression expression, TypeProvider typeProvider) {
-    if (expression instanceof TernaryExpression) {
-      updateTypeProvider(((TernaryExpression) expression).getFirstExpression(), typeProvider);
-      updateTypeProvider(((TernaryExpression) expression).getSecondExpression(), typeProvider);
-      updateTypeProvider(((TernaryExpression) expression).getThirdExpression(), typeProvider);
-    } else if (expression instanceof BinaryExpression) {
-      updateTypeProvider(((BinaryExpression) expression).getLeftExpression(), typeProvider);
-      updateTypeProvider(((BinaryExpression) expression).getRightExpression(), typeProvider);
-    } else if (expression instanceof UnaryExpression) {
-      updateTypeProvider(((UnaryExpression) expression).getExpression(), typeProvider);
-    } else if (expression instanceof FunctionExpression) {
-      for (Expression childExpression : expression.getExpressions()) {
-        updateTypeProvider(childExpression, typeProvider);
-      }
-    } else if (expression instanceof TimeSeriesOperand) {
-      PartialPath rawPath = ((TimeSeriesOperand) expression).getPath();
-      typeProvider.setType(
-          rawPath.isMeasurementAliasExists()
-              ? rawPath.getFullPathWithAlias()
-              : rawPath.getFullPath(),
-          rawPath.getSeriesType());
-    } else if (expression instanceof ConstantOperand || expression instanceof TimestampOperand) {
-      // do nothing
-    } else {
-      throw new IllegalArgumentException(
-          "unsupported expression type: " + expression.getExpressionType());
-    }
-  }
-
   /**
    * Remove alias from expression. eg: root.sg.d1.status + 1 -> root.sg.d1.s2 + 1
    *
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/GroupByLevelController.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/GroupByLevelController.java
index ce6dfa03da..24f69fd3b6 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/GroupByLevelController.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/GroupByLevelController.java
@@ -68,13 +68,13 @@ public class GroupByLevelController {
 
   private final TypeProvider typeProvider;
 
-  public GroupByLevelController(int[] levels, TypeProvider typeProvider) {
+  public GroupByLevelController(int[] levels) {
     this.levels = levels;
     this.groupedPathMap = new LinkedHashMap<>();
     this.rawPathToGroupedPathMap = new HashMap<>();
     this.columnToAliasMap = new HashMap<>();
     this.aliasToColumnMap = new HashMap<>();
-    this.typeProvider = typeProvider;
+    this.typeProvider = new TypeProvider();
   }
 
   public void control(boolean isCountStar, Expression expression, String alias) {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
index afa7e34806..d2ead1276d 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
@@ -101,8 +101,11 @@ public class LogicalPlanBuilder {
 
   private final MPPQueryContext context;
 
-  public LogicalPlanBuilder(MPPQueryContext context) {
+  private final SymbolAllocator symbolAllocator;
+
+  public LogicalPlanBuilder(MPPQueryContext context, SymbolAllocator symbolAllocator) {
     this.context = context;
+    this.symbolAllocator = symbolAllocator;
   }
 
   public PlanNode getRoot() {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
index 87d59a3e2e..b66c3cfcf2 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
@@ -78,6 +78,7 @@ import java.util.stream.Collectors;
 public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryContext> {
 
   private final Analysis analysis;
+  private final SymbolAllocator symbolAllocator = new SymbolAllocator();
 
   public LogicalPlanVisitor(Analysis analysis) {
     this.analysis = analysis;
@@ -91,7 +92,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
 
   @Override
   public PlanNode visitQuery(QueryStatement queryStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
 
     if (queryStatement.isLastQuery()) {
       return planBuilder
@@ -105,7 +106,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
     if (queryStatement.isAlignByDevice()) {
       Map<String, PlanNode> deviceToSubPlanMap = new TreeMap<>();
       for (String deviceName : analysis.getDeviceToSourceExpressions().keySet()) {
-        LogicalPlanBuilder subPlanBuilder = new LogicalPlanBuilder(context);
+        LogicalPlanBuilder subPlanBuilder = new LogicalPlanBuilder(context, symbolAllocator);
         subPlanBuilder =
             subPlanBuilder.withNewRoot(
                 visitQueryBody(
@@ -171,7 +172,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
       Expression havingExpression,
       List<Integer> measurementIndexes, // only used in ALIGN BY DEVICE
       MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
 
     // plan data source node
     if (isRawDataSource) {
@@ -483,7 +484,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowTimeSeries(
       ShowTimeSeriesStatement showTimeSeriesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
 
     // If there is only one region, we can push down the offset and limit operation to
     // source operator.
@@ -519,7 +520,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
         && null != analysis.getDataPartitionInfo()
         && 0 != analysis.getDataPartitionInfo().getDataPartitionMap().size()) {
       PlanNode lastPlanNode =
-          new LogicalPlanBuilder(context)
+          new LogicalPlanBuilder(context, symbolAllocator)
               .planLast(
                   analysis.getSourceExpressions(),
                   analysis.getGlobalTimeFilter(),
@@ -541,7 +542,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowDevices(
       ShowDevicesStatement showDevicesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
 
     // If there is only one region, we can push down the offset and limit operation to
     // source operator.
@@ -578,7 +579,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitCountDevices(
       CountDevicesStatement countDevicesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
     return planBuilder
         .planDevicesCountSource(
             countDevicesStatement.getPathPattern(), countDevicesStatement.isPrefixPath())
@@ -589,7 +590,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitCountTimeSeries(
       CountTimeSeriesStatement countTimeSeriesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
     return planBuilder
         .planTimeSeriesCountSource(
             countTimeSeriesStatement.getPathPattern(),
@@ -605,7 +606,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitCountLevelTimeSeries(
       CountLevelTimeSeriesStatement countLevelTimeSeriesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
     return planBuilder
         .planLevelTimeSeriesCountSource(
             countLevelTimeSeriesStatement.getPathPattern(),
@@ -620,7 +621,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
 
   @Override
   public PlanNode visitCountNodes(CountNodesStatement countStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
     return planBuilder
         .planNodePathsSchemaSource(countStatement.getPathPattern(), countStatement.getLevel())
         .planSchemaQueryMerge(false)
@@ -710,7 +711,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitSchemaFetch(
       SchemaFetchStatement schemaFetchStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
     List<String> storageGroupList =
         new ArrayList<>(analysis.getSchemaPartitionInfo().getSchemaPartitionMap().keySet());
     return planBuilder
@@ -725,7 +726,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowChildPaths(
       ShowChildPathsStatement showChildPathsStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
     return planBuilder
         .planNodePathsSchemaSource(showChildPathsStatement.getPartialPath(), -1)
         .planSchemaQueryMerge(false)
@@ -736,7 +737,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowChildNodes(
       ShowChildNodesStatement showChildNodesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
     return planBuilder
         .planNodePathsSchemaSource(showChildNodesStatement.getPartialPath(), -1)
         .planSchemaQueryMerge(false)
@@ -768,7 +769,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowPathsUsingTemplate(
       ShowPathsUsingTemplateStatement showPathsUsingTemplateStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
     planBuilder =
         planBuilder
             .planPathsUsingTemplateSource(analysis.getTemplateSetInfo().left.getId())
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/Symbol.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/Symbol.java
new file mode 100644
index 0000000000..ef8e1e2b44
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/Symbol.java
@@ -0,0 +1,29 @@
+/*
+ * 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.mpp.plan.planner;
+
+public class Symbol {
+
+  private final String name;
+
+  public Symbol(String name) {
+    this.name = name;
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SymbolAllocator.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SymbolAllocator.java
new file mode 100644
index 0000000000..f596800d85
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SymbolAllocator.java
@@ -0,0 +1,66 @@
+/*
+ * 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.mpp.plan.planner;
+
+import org.apache.iotdb.db.mpp.plan.expression.Expression;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class SymbolAllocator {
+
+  private final Map<Symbol, TSDataType> symbols;
+  private int nextId;
+
+  public SymbolAllocator() {
+    symbols = new HashMap<>();
+  }
+
+  public Symbol newSymbol(Expression expression, TSDataType type) {
+    String nameHint = "expr";
+    if (expression instanceof TimeSeriesOperand) {
+      nameHint = "series";
+    } else if (expression instanceof FunctionExpression) {
+      FunctionExpression functionExpression = (FunctionExpression) expression;
+      nameHint = functionExpression.getFunctionName();
+    }
+    return newSymbol(nameHint, type);
+  }
+
+  public Symbol newSymbol(String nameHint, TSDataType type) {
+    nameHint = nameHint.toLowerCase();
+
+    String unique = nameHint;
+
+    Symbol symbol = new Symbol(unique);
+    while (symbols.putIfAbsent(symbol, type) != null) {
+      symbol = new Symbol(unique + "_" + nextId());
+    }
+
+    return symbol;
+  }
+
+  private int nextId() {
+    return nextId++;
+  }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java
index b150d8d6f8..31243734aa 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java
@@ -27,6 +27,7 @@ import org.apache.iotdb.db.mpp.common.QueryId;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.planner.LogicalPlanBuilder;
+import org.apache.iotdb.db.mpp.plan.planner.SymbolAllocator;
 import org.apache.iotdb.db.mpp.plan.planner.distribution.DistributionPlanner;
 import org.apache.iotdb.db.mpp.plan.planner.plan.DistributedQueryPlan;
 import org.apache.iotdb.db.mpp.plan.planner.plan.LogicalQueryPlan;
@@ -197,7 +198,7 @@ public class LastQueryTest {
 
   private LogicalQueryPlan constructLastQuery(List<String> paths, MPPQueryContext context)
       throws IllegalPathException {
-    LogicalPlanBuilder builder = new LogicalPlanBuilder(context);
+    LogicalPlanBuilder builder = new LogicalPlanBuilder(context, new SymbolAllocator());
     Set<Expression> expressions = new HashSet<>();
     for (String path : paths) {
       expressions.add(new TimeSeriesOperand(new MeasurementPath(path)));


[iotdb] 04/07: remove SymbolAllocator

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

hui pushed a commit to branch lmh/TypeProviderOpt
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 9f3e3ccf1b97500ed839545465475afd3d256880
Author: Minghui Liu <li...@foxmail.com>
AuthorDate: Wed Sep 7 14:08:43 2022 +0800

    remove SymbolAllocator
---
 .../db/mpp/plan/planner/LogicalPlanBuilder.java    |  5 +-
 .../db/mpp/plan/planner/LogicalPlanVisitor.java    | 29 +++++-----
 .../apache/iotdb/db/mpp/plan/planner/Symbol.java   | 29 ----------
 .../iotdb/db/mpp/plan/planner/SymbolAllocator.java | 66 ----------------------
 .../mpp/plan/plan/distribution/LastQueryTest.java  |  3 +-
 5 files changed, 16 insertions(+), 116 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
index d2ead1276d..afa7e34806 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
@@ -101,11 +101,8 @@ public class LogicalPlanBuilder {
 
   private final MPPQueryContext context;
 
-  private final SymbolAllocator symbolAllocator;
-
-  public LogicalPlanBuilder(MPPQueryContext context, SymbolAllocator symbolAllocator) {
+  public LogicalPlanBuilder(MPPQueryContext context) {
     this.context = context;
-    this.symbolAllocator = symbolAllocator;
   }
 
   public PlanNode getRoot() {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
index b66c3cfcf2..87d59a3e2e 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
@@ -78,7 +78,6 @@ import java.util.stream.Collectors;
 public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryContext> {
 
   private final Analysis analysis;
-  private final SymbolAllocator symbolAllocator = new SymbolAllocator();
 
   public LogicalPlanVisitor(Analysis analysis) {
     this.analysis = analysis;
@@ -92,7 +91,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
 
   @Override
   public PlanNode visitQuery(QueryStatement queryStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
 
     if (queryStatement.isLastQuery()) {
       return planBuilder
@@ -106,7 +105,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
     if (queryStatement.isAlignByDevice()) {
       Map<String, PlanNode> deviceToSubPlanMap = new TreeMap<>();
       for (String deviceName : analysis.getDeviceToSourceExpressions().keySet()) {
-        LogicalPlanBuilder subPlanBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+        LogicalPlanBuilder subPlanBuilder = new LogicalPlanBuilder(context);
         subPlanBuilder =
             subPlanBuilder.withNewRoot(
                 visitQueryBody(
@@ -172,7 +171,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
       Expression havingExpression,
       List<Integer> measurementIndexes, // only used in ALIGN BY DEVICE
       MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
 
     // plan data source node
     if (isRawDataSource) {
@@ -484,7 +483,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowTimeSeries(
       ShowTimeSeriesStatement showTimeSeriesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
 
     // If there is only one region, we can push down the offset and limit operation to
     // source operator.
@@ -520,7 +519,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
         && null != analysis.getDataPartitionInfo()
         && 0 != analysis.getDataPartitionInfo().getDataPartitionMap().size()) {
       PlanNode lastPlanNode =
-          new LogicalPlanBuilder(context, symbolAllocator)
+          new LogicalPlanBuilder(context)
               .planLast(
                   analysis.getSourceExpressions(),
                   analysis.getGlobalTimeFilter(),
@@ -542,7 +541,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowDevices(
       ShowDevicesStatement showDevicesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
 
     // If there is only one region, we can push down the offset and limit operation to
     // source operator.
@@ -579,7 +578,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitCountDevices(
       CountDevicesStatement countDevicesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
     return planBuilder
         .planDevicesCountSource(
             countDevicesStatement.getPathPattern(), countDevicesStatement.isPrefixPath())
@@ -590,7 +589,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitCountTimeSeries(
       CountTimeSeriesStatement countTimeSeriesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
     return planBuilder
         .planTimeSeriesCountSource(
             countTimeSeriesStatement.getPathPattern(),
@@ -606,7 +605,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitCountLevelTimeSeries(
       CountLevelTimeSeriesStatement countLevelTimeSeriesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
     return planBuilder
         .planLevelTimeSeriesCountSource(
             countLevelTimeSeriesStatement.getPathPattern(),
@@ -621,7 +620,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
 
   @Override
   public PlanNode visitCountNodes(CountNodesStatement countStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
     return planBuilder
         .planNodePathsSchemaSource(countStatement.getPathPattern(), countStatement.getLevel())
         .planSchemaQueryMerge(false)
@@ -711,7 +710,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitSchemaFetch(
       SchemaFetchStatement schemaFetchStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
     List<String> storageGroupList =
         new ArrayList<>(analysis.getSchemaPartitionInfo().getSchemaPartitionMap().keySet());
     return planBuilder
@@ -726,7 +725,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowChildPaths(
       ShowChildPathsStatement showChildPathsStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
     return planBuilder
         .planNodePathsSchemaSource(showChildPathsStatement.getPartialPath(), -1)
         .planSchemaQueryMerge(false)
@@ -737,7 +736,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowChildNodes(
       ShowChildNodesStatement showChildNodesStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
     return planBuilder
         .planNodePathsSchemaSource(showChildNodesStatement.getPartialPath(), -1)
         .planSchemaQueryMerge(false)
@@ -769,7 +768,7 @@ public class LogicalPlanVisitor extends StatementVisitor<PlanNode, MPPQueryConte
   @Override
   public PlanNode visitShowPathsUsingTemplate(
       ShowPathsUsingTemplateStatement showPathsUsingTemplateStatement, MPPQueryContext context) {
-    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context, symbolAllocator);
+    LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(context);
     planBuilder =
         planBuilder
             .planPathsUsingTemplateSource(analysis.getTemplateSetInfo().left.getId())
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/Symbol.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/Symbol.java
deleted file mode 100644
index ef8e1e2b44..0000000000
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/Symbol.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.mpp.plan.planner;
-
-public class Symbol {
-
-  private final String name;
-
-  public Symbol(String name) {
-    this.name = name;
-  }
-}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SymbolAllocator.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SymbolAllocator.java
deleted file mode 100644
index f596800d85..0000000000
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SymbolAllocator.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.mpp.plan.planner;
-
-import org.apache.iotdb.db.mpp.plan.expression.Expression;
-import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
-import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class SymbolAllocator {
-
-  private final Map<Symbol, TSDataType> symbols;
-  private int nextId;
-
-  public SymbolAllocator() {
-    symbols = new HashMap<>();
-  }
-
-  public Symbol newSymbol(Expression expression, TSDataType type) {
-    String nameHint = "expr";
-    if (expression instanceof TimeSeriesOperand) {
-      nameHint = "series";
-    } else if (expression instanceof FunctionExpression) {
-      FunctionExpression functionExpression = (FunctionExpression) expression;
-      nameHint = functionExpression.getFunctionName();
-    }
-    return newSymbol(nameHint, type);
-  }
-
-  public Symbol newSymbol(String nameHint, TSDataType type) {
-    nameHint = nameHint.toLowerCase();
-
-    String unique = nameHint;
-
-    Symbol symbol = new Symbol(unique);
-    while (symbols.putIfAbsent(symbol, type) != null) {
-      symbol = new Symbol(unique + "_" + nextId());
-    }
-
-    return symbol;
-  }
-
-  private int nextId() {
-    return nextId++;
-  }
-}
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java
index 31243734aa..b150d8d6f8 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/LastQueryTest.java
@@ -27,7 +27,6 @@ import org.apache.iotdb.db.mpp.common.QueryId;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.planner.LogicalPlanBuilder;
-import org.apache.iotdb.db.mpp.plan.planner.SymbolAllocator;
 import org.apache.iotdb.db.mpp.plan.planner.distribution.DistributionPlanner;
 import org.apache.iotdb.db.mpp.plan.planner.plan.DistributedQueryPlan;
 import org.apache.iotdb.db.mpp.plan.planner.plan.LogicalQueryPlan;
@@ -198,7 +197,7 @@ public class LastQueryTest {
 
   private LogicalQueryPlan constructLastQuery(List<String> paths, MPPQueryContext context)
       throws IllegalPathException {
-    LogicalPlanBuilder builder = new LogicalPlanBuilder(context, new SymbolAllocator());
+    LogicalPlanBuilder builder = new LogicalPlanBuilder(context);
     Set<Expression> expressions = new HashSet<>();
     for (String path : paths) {
       expressions.add(new TimeSeriesOperand(new MeasurementPath(path)));


[iotdb] 06/07: re-analyze expression in OperatorTreeGenerator

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

hui pushed a commit to branch lmh/TypeProviderOpt
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 7d888bf409d1214faee1edd9808f1564ae007b90
Author: Minghui Liu <li...@foxmail.com>
AuthorDate: Wed Sep 7 16:40:33 2022 +0800

    re-analyze expression in OperatorTreeGenerator
---
 .../mpp/plan/analyze/ExpressionTypeAnalyzer.java   |  8 +++
 .../iotdb/db/mpp/plan/expression/Expression.java   |  5 +-
 .../plan/expression/binary/BinaryExpression.java   |  8 ++-
 .../db/mpp/plan/expression/leaf/LeafOperand.java   |  5 +-
 .../plan/expression/multi/FunctionExpression.java  |  7 ++-
 .../plan/expression/ternary/TernaryExpression.java | 11 ++--
 .../mpp/plan/expression/unary/UnaryExpression.java |  7 ++-
 .../visitor/ColumnTransformerVisitor.java          | 69 ++++++++--------------
 .../db/mpp/plan/planner/OperatorTreeGenerator.java | 27 ++++++---
 9 files changed, 78 insertions(+), 69 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionTypeAnalyzer.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionTypeAnalyzer.java
index 98d193dccc..bc642769da 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionTypeAnalyzer.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionTypeAnalyzer.java
@@ -61,6 +61,14 @@ public class ExpressionTypeAnalyzer {
     updateAnalysis(analysis, analyzer);
   }
 
+  public static void analyzeExpression(
+      Map<NodeRef<Expression>, TSDataType> types, Expression expression) {
+    ExpressionTypeAnalyzer analyzer = new ExpressionTypeAnalyzer();
+    analyzer.analyze(expression);
+
+    types.putAll(analyzer.getExpressionTypes());
+  }
+
   private static void updateAnalysis(Analysis analysis, ExpressionTypeAnalyzer analyzer) {
     analysis.addTypes(analyzer.getExpressionTypes());
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/Expression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/Expression.java
index 0e00a37555..3847412f71 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/Expression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/Expression.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.db.mpp.plan.expression;
 
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.mpp.common.NodeRef;
 import org.apache.iotdb.db.mpp.plan.expression.binary.AdditionExpression;
 import org.apache.iotdb.db.mpp.plan.expression.binary.DivisionExpression;
 import org.apache.iotdb.db.mpp.plan.expression.binary.EqualToExpression;
@@ -52,6 +52,7 @@ import org.apache.iotdb.db.mpp.plan.statement.StatementNode;
 import org.apache.iotdb.db.mpp.transformation.dag.memory.LayerMemoryAssigner;
 import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFExecutor;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.io.DataOutputStream;
@@ -99,7 +100,7 @@ public abstract class Expression extends StatementNode {
     return false;
   }
 
-  public abstract boolean isMappable(TypeProvider typeProvider);
+  public abstract boolean isMappable(Map<NodeRef<Expression>, TSDataType> expressionTypes);
 
   /////////////////////////////////////////////////////////////////////////////////////////////////
   // isConstantOperand
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/BinaryExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/BinaryExpression.java
index 5a0732dbb3..58722f7da5 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/BinaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/BinaryExpression.java
@@ -21,13 +21,14 @@ package org.apache.iotdb.db.mpp.plan.expression.binary;
 
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.mpp.common.NodeRef;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.InputLocation;
 import org.apache.iotdb.db.mpp.transformation.dag.memory.LayerMemoryAssigner;
 import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFExecutor;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -217,8 +218,9 @@ public abstract class BinaryExpression extends Expression {
   }
 
   @Override
-  public boolean isMappable(TypeProvider typeProvider) {
-    return leftExpression.isMappable(typeProvider) && rightExpression.isMappable(typeProvider);
+  public boolean isMappable(Map<NodeRef<Expression>, TSDataType> expressionTypes) {
+    return leftExpression.isMappable(expressionTypes)
+        && rightExpression.isMappable(expressionTypes);
   }
 
   @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/LeafOperand.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/LeafOperand.java
index ab36096756..c614c9fb9e 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/LeafOperand.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/LeafOperand.java
@@ -19,9 +19,10 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.leaf;
 
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.mpp.common.NodeRef;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFExecutor;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.time.ZoneId;
 import java.util.Collections;
@@ -42,7 +43,7 @@ public abstract class LeafOperand extends Expression {
   }
 
   @Override
-  public boolean isMappable(TypeProvider typeProvider) {
+  public boolean isMappable(Map<NodeRef<Expression>, TSDataType> expressionTypes) {
     return true;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java
index 197fa1b41e..a40e6fe106 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java
@@ -23,7 +23,7 @@ import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.mpp.common.NodeRef;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
@@ -34,6 +34,7 @@ import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFExecutor;
 import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFInformationInferrer;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
 import org.apache.iotdb.db.qp.strategy.optimizer.ConcatPathOptimizer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 import org.apache.iotdb.udf.api.customizer.strategy.AccessStrategy;
 
@@ -269,7 +270,7 @@ public class FunctionExpression extends Expression {
   }
 
   @Override
-  public boolean isMappable(TypeProvider typeProvider) {
+  public boolean isMappable(Map<NodeRef<Expression>, TSDataType> expressionTypes) {
     if (isBuiltInAggregationFunctionExpression) {
       return true;
     }
@@ -277,7 +278,7 @@ public class FunctionExpression extends Expression {
         .getAccessStrategy(
             expressions.stream().map(Expression::toString).collect(Collectors.toList()),
             expressions.stream()
-                .map(f -> typeProvider.getType(f.toString()))
+                .map(f -> expressionTypes.get(NodeRef.of(f)))
                 .collect(Collectors.toList()),
             functionAttributes)
         .getAccessStrategyType()
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/TernaryExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/TernaryExpression.java
index 80725eab5f..b37ad2520c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/TernaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/TernaryExpression.java
@@ -23,13 +23,14 @@ package org.apache.iotdb.db.mpp.plan.expression.ternary;
 
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.mpp.common.NodeRef;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.InputLocation;
 import org.apache.iotdb.db.mpp.transformation.dag.memory.LayerMemoryAssigner;
 import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFExecutor;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -158,10 +159,10 @@ public abstract class TernaryExpression extends Expression {
   }
 
   @Override
-  public boolean isMappable(TypeProvider typeProvider) {
-    return firstExpression.isMappable(typeProvider)
-        && secondExpression.isMappable(typeProvider)
-        && thirdExpression.isMappable(typeProvider);
+  public boolean isMappable(Map<NodeRef<Expression>, TSDataType> expressionTypes) {
+    return firstExpression.isMappable(expressionTypes)
+        && secondExpression.isMappable(expressionTypes)
+        && thirdExpression.isMappable(expressionTypes);
   }
 
   @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/UnaryExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/UnaryExpression.java
index e53fd40d0a..f006a32350 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/UnaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/UnaryExpression.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.db.mpp.plan.expression.unary;
 
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.mpp.common.NodeRef;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.InputLocation;
@@ -29,6 +29,7 @@ import org.apache.iotdb.db.mpp.transformation.dag.memory.LayerMemoryAssigner;
 import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFExecutor;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
 import org.apache.iotdb.db.qp.utils.WildcardsRemover;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -113,8 +114,8 @@ public abstract class UnaryExpression extends Expression {
   }
 
   @Override
-  public boolean isMappable(TypeProvider typeProvider) {
-    return expression.isMappable(typeProvider);
+  public boolean isMappable(Map<NodeRef<Expression>, TSDataType> expressionTypes) {
+    return expression.isMappable(expressionTypes);
   }
 
   @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ColumnTransformerVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ColumnTransformerVisitor.java
index 313082a8df..148e4009e7 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ColumnTransformerVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ColumnTransformerVisitor.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.visitor;
 
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.mpp.common.NodeRef;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.binary.BinaryExpression;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
@@ -89,15 +89,13 @@ public class ColumnTransformerVisitor
       if (context.hasSeen.containsKey(unaryExpression)) {
         IdentityColumnTransformer identity =
             new IdentityColumnTransformer(
-                TypeFactory.getType(
-                    context.typeProvider.getType(unaryExpression.getExpressionString())),
+                TypeFactory.getType(context.getType(unaryExpression)),
                 context.originSize + context.commonTransformerList.size());
         ColumnTransformer columnTransformer = context.hasSeen.get(unaryExpression);
         columnTransformer.addReferenceCount();
         context.commonTransformerList.add(columnTransformer);
         context.leafList.add(identity);
-        context.inputDataTypes.add(
-            context.typeProvider.getType(unaryExpression.getExpressionString()));
+        context.inputDataTypes.add(context.getType(unaryExpression));
         context.cache.put(unaryExpression, identity);
       } else {
         ColumnTransformer childColumnTransformer =
@@ -107,8 +105,7 @@ public class ColumnTransformerVisitor
             getConcreteUnaryColumnTransformer(
                 unaryExpression,
                 childColumnTransformer,
-                TypeFactory.getType(
-                    context.typeProvider.getType(unaryExpression.getExpressionString()))));
+                TypeFactory.getType(context.getType(unaryExpression))));
       }
     }
     ColumnTransformer res = context.cache.get(unaryExpression);
@@ -123,15 +120,13 @@ public class ColumnTransformerVisitor
       if (context.hasSeen.containsKey(binaryExpression)) {
         IdentityColumnTransformer identity =
             new IdentityColumnTransformer(
-                TypeFactory.getType(
-                    context.typeProvider.getType(binaryExpression.getExpressionString())),
+                TypeFactory.getType(context.getType(binaryExpression)),
                 context.originSize + context.commonTransformerList.size());
         ColumnTransformer columnTransformer = context.hasSeen.get(binaryExpression);
         columnTransformer.addReferenceCount();
         context.commonTransformerList.add(columnTransformer);
         context.leafList.add(identity);
-        context.inputDataTypes.add(
-            context.typeProvider.getType(binaryExpression.getExpressionString()));
+        context.inputDataTypes.add(context.getType(binaryExpression));
         context.cache.put(binaryExpression, identity);
       } else {
         ColumnTransformer leftColumnTransformer =
@@ -144,8 +139,7 @@ public class ColumnTransformerVisitor
                 binaryExpression,
                 leftColumnTransformer,
                 rightColumnTransformer,
-                TypeFactory.getType(
-                    context.typeProvider.getType(binaryExpression.getExpressionString()))));
+                TypeFactory.getType(context.getType(binaryExpression))));
       }
     }
 
@@ -161,15 +155,13 @@ public class ColumnTransformerVisitor
       if (context.hasSeen.containsKey(ternaryExpression)) {
         IdentityColumnTransformer identity =
             new IdentityColumnTransformer(
-                TypeFactory.getType(
-                    context.typeProvider.getType(ternaryExpression.getExpressionString())),
+                TypeFactory.getType(context.getType(ternaryExpression)),
                 context.originSize + context.commonTransformerList.size());
         ColumnTransformer columnTransformer = context.hasSeen.get(ternaryExpression);
         columnTransformer.addReferenceCount();
         context.commonTransformerList.add(columnTransformer);
         context.leafList.add(identity);
-        context.inputDataTypes.add(
-            context.typeProvider.getType(ternaryExpression.getExpressionString()));
+        context.inputDataTypes.add(context.getType(ternaryExpression));
         context.cache.put(ternaryExpression, identity);
       } else {
         ColumnTransformer firstColumnTransformer =
@@ -185,8 +177,7 @@ public class ColumnTransformerVisitor
                 firstColumnTransformer,
                 secondColumnTransformer,
                 thirdColumnTransformer,
-                TypeFactory.getType(
-                    context.typeProvider.getType(ternaryExpression.getExpressionString()))));
+                TypeFactory.getType(context.getType(ternaryExpression))));
       }
     }
 
@@ -203,22 +194,19 @@ public class ColumnTransformerVisitor
       if (context.hasSeen.containsKey(functionExpression)) {
         IdentityColumnTransformer identity =
             new IdentityColumnTransformer(
-                TypeFactory.getType(
-                    context.typeProvider.getType(functionExpression.getExpressionString())),
+                TypeFactory.getType(context.getType(functionExpression)),
                 context.originSize + context.commonTransformerList.size());
         ColumnTransformer columnTransformer = context.hasSeen.get(functionExpression);
         columnTransformer.addReferenceCount();
         context.commonTransformerList.add(columnTransformer);
-        context.inputDataTypes.add(
-            context.typeProvider.getType(functionExpression.getExpressionString()));
+        context.inputDataTypes.add(context.getType(functionExpression));
         context.leafList.add(identity);
         context.cache.put(functionExpression, identity);
       } else {
         if (functionExpression.isBuiltInAggregationFunctionExpression()) {
           IdentityColumnTransformer identity =
               new IdentityColumnTransformer(
-                  TypeFactory.getType(
-                      context.typeProvider.getType(functionExpression.getExpressionString())),
+                  TypeFactory.getType(context.getType(functionExpression)),
                   context
                       .inputLocations
                       .get(functionExpression.getExpressionString())
@@ -233,9 +221,7 @@ public class ColumnTransformerVisitor
                   .toArray(ColumnTransformer[]::new);
 
           TSDataType[] inputTransformerDataTypes =
-              expressions.stream()
-                  .map(expression -> expression.inferTypes(context.typeProvider))
-                  .toArray(TSDataType[]::new);
+              expressions.stream().map(context::getType).toArray(TSDataType[]::new);
 
           UDTFExecutor executor =
               context.udtfContext.getExecutorByFunctionExpression(functionExpression);
@@ -246,16 +232,13 @@ public class ColumnTransformerVisitor
               0,
               0,
               expressions.stream().map(Expression::toString).collect(Collectors.toList()),
-              expressions.stream()
-                  .map(f -> context.typeProvider.getType(f.toString()))
-                  .collect(Collectors.toList()),
+              expressions.stream().map(context::getType).collect(Collectors.toList()),
               functionExpression.getFunctionAttributes());
 
           context.cache.put(
               functionExpression,
               new MappableUDFColumnTransformer(
-                  TypeFactory.getType(
-                      context.typeProvider.getType(functionExpression.getExpressionString())),
+                  TypeFactory.getType(context.getType(functionExpression)),
                   inputColumnTransformers,
                   inputTransformerDataTypes,
                   context.udtfContext.getExecutorByFunctionExpression(functionExpression)));
@@ -275,9 +258,7 @@ public class ColumnTransformerVisitor
             timestampOperand,
             e -> {
               TimeColumnTransformer timeColumnTransformer =
-                  new TimeColumnTransformer(
-                      TypeFactory.getType(
-                          context.typeProvider.getType(timestampOperand.getExpressionString())));
+                  new TimeColumnTransformer(TypeFactory.getType(context.getType(timestampOperand)));
               context.leafList.add(timeColumnTransformer);
               return timeColumnTransformer;
             });
@@ -294,8 +275,7 @@ public class ColumnTransformerVisitor
             e -> {
               IdentityColumnTransformer identity =
                   new IdentityColumnTransformer(
-                      TypeFactory.getType(
-                          context.typeProvider.getType(timeSeriesOperand.getExpressionString())),
+                      TypeFactory.getType(context.getType(timeSeriesOperand)),
                       context
                           .inputLocations
                           .get(timeSeriesOperand.getExpressionString())
@@ -317,8 +297,7 @@ public class ColumnTransformerVisitor
             e -> {
               ConstantColumnTransformer columnTransformer =
                   new ConstantColumnTransformer(
-                      TypeFactory.getType(
-                          context.typeProvider.getType(constantOperand.getExpressionString())),
+                      TypeFactory.getType(context.getType(constantOperand)),
                       TransformUtils.transformConstantOperandToColumn(constantOperand));
               context.leafList.add(columnTransformer);
               return columnTransformer;
@@ -433,7 +412,7 @@ public class ColumnTransformerVisitor
     UDTFContext udtfContext;
 
     // TypeProvider of expression
-    TypeProvider typeProvider;
+    Map<NodeRef<Expression>, TSDataType> expressionTypes;
 
     // LeafColumnTransformer for LeafOperand
     List<LeafColumnTransformer> leafList;
@@ -456,7 +435,7 @@ public class ColumnTransformerVisitor
 
     public ColumnTransformerVisitorContext(
         UDTFContext udtfContext,
-        TypeProvider typeProvider,
+        Map<NodeRef<Expression>, TSDataType> expressionTypes,
         List<LeafColumnTransformer> leafList,
         Map<String, List<InputLocation>> inputLocations,
         Map<Expression, ColumnTransformer> cache,
@@ -465,7 +444,7 @@ public class ColumnTransformerVisitor
         List<TSDataType> inputDataTypes,
         int originSize) {
       this.udtfContext = udtfContext;
-      this.typeProvider = typeProvider;
+      this.expressionTypes = expressionTypes;
       this.leafList = leafList;
       this.inputLocations = inputLocations;
       this.cache = cache;
@@ -474,5 +453,9 @@ public class ColumnTransformerVisitor
       this.inputDataTypes = inputDataTypes;
       this.originSize = originSize;
     }
+
+    public TSDataType getType(Expression expression) {
+      return expressionTypes.get(NodeRef.of(expression));
+    }
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
index 06dd05b6fa..8aaa3b8dd5 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java
@@ -29,6 +29,7 @@ import org.apache.iotdb.db.mpp.aggregation.Aggregator;
 import org.apache.iotdb.db.mpp.aggregation.slidingwindow.SlidingWindowAggregatorFactory;
 import org.apache.iotdb.db.mpp.aggregation.timerangeiterator.ITimeRangeIterator;
 import org.apache.iotdb.db.mpp.common.FragmentInstanceId;
+import org.apache.iotdb.db.mpp.common.NodeRef;
 import org.apache.iotdb.db.mpp.execution.driver.SchemaDriverContext;
 import org.apache.iotdb.db.mpp.execution.exchange.ISinkHandle;
 import org.apache.iotdb.db.mpp.execution.exchange.ISourceHandle;
@@ -104,6 +105,7 @@ import org.apache.iotdb.db.mpp.execution.operator.source.AlignedSeriesScanOperat
 import org.apache.iotdb.db.mpp.execution.operator.source.ExchangeOperator;
 import org.apache.iotdb.db.mpp.execution.operator.source.SeriesAggregationScanOperator;
 import org.apache.iotdb.db.mpp.execution.operator.source.SeriesScanOperator;
+import org.apache.iotdb.db.mpp.plan.analyze.ExpressionTypeAnalyzer;
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
@@ -821,13 +823,17 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP
     final List<TSDataType> inputDataTypes = getInputColumnTypes(node, context.getTypeProvider());
     final Map<String, List<InputLocation>> inputLocations = makeLayout(node);
     final Expression[] projectExpressions = node.getOutputExpressions();
-    final TypeProvider typeProvider = context.getTypeProvider();
+    final Map<NodeRef<Expression>, TSDataType> expressionTypes = new HashMap<>();
+
+    for (Expression projectExpression : projectExpressions) {
+      ExpressionTypeAnalyzer.analyzeExpression(expressionTypes, projectExpression);
+    }
 
     context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, 1);
 
     boolean hasNonMappableUDF = false;
     for (Expression expression : projectExpressions) {
-      if (!expression.isMappable(typeProvider)) {
+      if (!expression.isMappable(expressionTypes)) {
         hasNonMappableUDF = true;
         break;
       }
@@ -849,7 +855,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP
       ColumnTransformerVisitor.ColumnTransformerVisitorContext projectColumnTransformerContext =
           new ColumnTransformerVisitor.ColumnTransformerVisitorContext(
               projectContext,
-              typeProvider,
+              expressionTypes,
               projectLeafColumnTransformerList,
               inputLocations,
               projectExpressionColumnTransformerMap,
@@ -895,10 +901,11 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP
   @Override
   public Operator visitFilter(FilterNode node, LocalExecutionPlanContext context) {
     final Expression filterExpression = node.getPredicate();
-    final TypeProvider typeProvider = context.getTypeProvider();
+    final Map<NodeRef<Expression>, TSDataType> expressionTypes = new HashMap<>();
+    ExpressionTypeAnalyzer.analyzeExpression(expressionTypes, filterExpression);
 
     // check whether predicate contains Non-Mappable UDF
-    if (!filterExpression.isMappable(typeProvider)) {
+    if (!filterExpression.isMappable(expressionTypes)) {
       throw new UnsupportedOperationException("Filter can not contain Non-Mappable UDF");
     }
 
@@ -916,9 +923,13 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP
                 FilterAndProjectOperator.class.getSimpleName());
     context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, 1);
 
+    for (Expression projectExpression : projectExpressions) {
+      ExpressionTypeAnalyzer.analyzeExpression(expressionTypes, projectExpression);
+    }
+
     boolean hasNonMappableUDF = false;
     for (Expression expression : projectExpressions) {
-      if (!expression.isMappable(typeProvider)) {
+      if (!expression.isMappable(expressionTypes)) {
         hasNonMappableUDF = true;
         break;
       }
@@ -945,7 +956,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP
     ColumnTransformerVisitor.ColumnTransformerVisitorContext filterColumnTransformerContext =
         new ColumnTransformerVisitor.ColumnTransformerVisitorContext(
             filterContext,
-            typeProvider,
+            expressionTypes,
             filterLeafColumnTransformerList,
             inputLocations,
             filterExpressionColumnTransformerMap,
@@ -970,7 +981,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP
       ColumnTransformerVisitor.ColumnTransformerVisitorContext projectColumnTransformerContext =
           new ColumnTransformerVisitor.ColumnTransformerVisitorContext(
               projectContext,
-              typeProvider,
+              expressionTypes,
               projectLeafColumnTransformerList,
               inputLocations,
               projectExpressionColumnTransformerMap,


[iotdb] 02/07: remove inferTypes in Expression

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

hui pushed a commit to branch lmh/TypeProviderOpt
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit babbe9c671a40524767cb1a57421c594a8c306a6
Author: Minghui Liu <li...@foxmail.com>
AuthorDate: Tue Sep 6 10:55:47 2022 +0800

    remove inferTypes in Expression
---
 .../iotdb/db/mpp/plan/expression/Expression.java   | 21 ---------
 .../binary/ArithmeticBinaryExpression.java         | 25 -----------
 .../expression/binary/CompareBinaryExpression.java | 50 ----------------------
 .../expression/binary/LogicBinaryExpression.java   | 15 -------
 .../mpp/plan/expression/leaf/ConstantOperand.java  |  7 ---
 .../plan/expression/leaf/TimeSeriesOperand.java    |  7 ---
 .../mpp/plan/expression/leaf/TimestampOperand.java |  8 ----
 .../plan/expression/multi/FunctionExpression.java  | 39 -----------------
 .../plan/expression/ternary/BetweenExpression.java | 14 ------
 .../db/mpp/plan/expression/unary/InExpression.java | 12 ------
 .../plan/expression/unary/IsNullExpression.java    | 12 ------
 .../mpp/plan/expression/unary/LikeExpression.java  | 14 ------
 .../plan/expression/unary/LogicNotExpression.java  | 14 ------
 .../plan/expression/unary/NegationExpression.java  | 20 ---------
 .../plan/expression/unary/RegularExpression.java   | 14 ------
 15 files changed, 272 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/Expression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/Expression.java
index 28d87a8ba2..0e00a37555 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/Expression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/Expression.java
@@ -21,7 +21,6 @@ package org.apache.iotdb.db.mpp.plan.expression;
 
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.binary.AdditionExpression;
 import org.apache.iotdb.db.mpp.plan.expression.binary.DivisionExpression;
@@ -53,14 +52,12 @@ import org.apache.iotdb.db.mpp.plan.statement.StatementNode;
 import org.apache.iotdb.db.mpp.transformation.dag.memory.LayerMemoryAssigner;
 import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFExecutor;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.time.ZoneId;
-import java.util.Arrays;
 import java.util.Deque;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -147,24 +144,6 @@ public abstract class Expression extends StatementNode {
   public abstract void constructUdfExecutors(
       Map<String, UDTFExecutor> expressionName2Executor, ZoneId zoneId);
 
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-  // type inference
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-  public abstract TSDataType inferTypes(TypeProvider typeProvider);
-
-  protected static void checkInputExpressionDataType(
-      String expressionString, TSDataType actual, TSDataType... expected) {
-    for (TSDataType type : expected) {
-      if (actual.equals(type)) {
-        return;
-      }
-    }
-    throw new SemanticException(
-        String.format(
-            "Invalid input expression data type. expression: %s, actual data type: %s, expected data type(s): %s.",
-            expressionString, actual.name(), Arrays.toString(expected)));
-  }
-
   /////////////////////////////////////////////////////////////////////////////////////////////////
   // For expression evaluation DAG building
   /////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/ArithmeticBinaryExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/ArithmeticBinaryExpression.java
index cb7d7eacec..d2189e2e47 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/ArithmeticBinaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/ArithmeticBinaryExpression.java
@@ -19,10 +19,8 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.binary;
 
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
 
@@ -36,29 +34,6 @@ public abstract class ArithmeticBinaryExpression extends BinaryExpression {
     super(byteBuffer);
   }
 
-  @Override
-  public final TSDataType inferTypes(TypeProvider typeProvider) {
-    final String expressionString = toString();
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      checkInputExpressionDataType(
-          leftExpression.toString(),
-          leftExpression.inferTypes(typeProvider),
-          TSDataType.INT32,
-          TSDataType.INT64,
-          TSDataType.FLOAT,
-          TSDataType.DOUBLE);
-      checkInputExpressionDataType(
-          rightExpression.toString(),
-          rightExpression.inferTypes(typeProvider),
-          TSDataType.INT32,
-          TSDataType.INT64,
-          TSDataType.FLOAT,
-          TSDataType.DOUBLE);
-      typeProvider.setType(expressionString, TSDataType.DOUBLE);
-    }
-    return TSDataType.DOUBLE;
-  }
-
   @Override
   public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
     return visitor.visitArithmeticBinaryExpression(this, context);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/CompareBinaryExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/CompareBinaryExpression.java
index 850d89b3df..8a3f109c5e 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/CompareBinaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/CompareBinaryExpression.java
@@ -19,10 +19,8 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.binary;
 
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
 
@@ -36,54 +34,6 @@ public abstract class CompareBinaryExpression extends BinaryExpression {
     super(byteBuffer);
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) {
-    final String expressionString = toString();
-
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      final TSDataType leftExpressionDataType = leftExpression.inferTypes(typeProvider);
-      final TSDataType rightExpressionDataType = rightExpression.inferTypes(typeProvider);
-
-      if (!leftExpressionDataType.equals(rightExpressionDataType)) {
-        final String leftExpressionString = leftExpression.toString();
-        final String rightExpressionString = rightExpression.toString();
-
-        if (TSDataType.BOOLEAN.equals(leftExpressionDataType)
-            || TSDataType.BOOLEAN.equals(rightExpressionDataType)) {
-          checkInputExpressionDataType(
-              leftExpressionString, leftExpressionDataType, TSDataType.BOOLEAN);
-          checkInputExpressionDataType(
-              rightExpressionString, rightExpressionDataType, TSDataType.BOOLEAN);
-        } else if (TSDataType.TEXT.equals(leftExpressionDataType)
-            || TSDataType.TEXT.equals(rightExpressionDataType)) {
-          checkInputExpressionDataType(
-              leftExpressionString, leftExpressionDataType, TSDataType.TEXT);
-          checkInputExpressionDataType(
-              rightExpressionString, rightExpressionDataType, TSDataType.TEXT);
-        } else {
-          checkInputExpressionDataType(
-              leftExpressionString,
-              leftExpressionDataType,
-              TSDataType.INT32,
-              TSDataType.INT64,
-              TSDataType.FLOAT,
-              TSDataType.DOUBLE);
-          checkInputExpressionDataType(
-              rightExpressionString,
-              rightExpressionDataType,
-              TSDataType.INT32,
-              TSDataType.INT64,
-              TSDataType.FLOAT,
-              TSDataType.DOUBLE);
-        }
-      }
-
-      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
-    }
-
-    return TSDataType.BOOLEAN;
-  }
-
   @Override
   public boolean isCompareBinaryExpression() {
     return true;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/LogicBinaryExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/LogicBinaryExpression.java
index 05bcd06fd2..e98ce86e82 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/LogicBinaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/LogicBinaryExpression.java
@@ -19,10 +19,8 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.binary;
 
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
 
@@ -36,19 +34,6 @@ public abstract class LogicBinaryExpression extends BinaryExpression {
     super(byteBuffer);
   }
 
-  @Override
-  public final TSDataType inferTypes(TypeProvider typeProvider) {
-    final String expressionString = toString();
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      checkInputExpressionDataType(
-          leftExpression.toString(), leftExpression.inferTypes(typeProvider), TSDataType.BOOLEAN);
-      checkInputExpressionDataType(
-          rightExpression.toString(), rightExpression.inferTypes(typeProvider), TSDataType.BOOLEAN);
-      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
-    }
-    return TSDataType.BOOLEAN;
-  }
-
   @Override
   public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
     return visitor.visitLogicBinaryExpression(this, context);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/ConstantOperand.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/ConstantOperand.java
index 8056c963a8..0d4801c3be 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/ConstantOperand.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/ConstantOperand.java
@@ -20,7 +20,6 @@
 package org.apache.iotdb.db.mpp.plan.expression.leaf;
 
 import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
@@ -96,12 +95,6 @@ public class ConstantOperand extends LeafOperand {
     // Do nothing
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) {
-    typeProvider.setType(toString(), dataType);
-    return dataType;
-  }
-
   @Override
   public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     // Do nothing
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/TimeSeriesOperand.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/TimeSeriesOperand.java
index 7195dc992e..7d80257dd8 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/TimeSeriesOperand.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/TimeSeriesOperand.java
@@ -22,14 +22,12 @@ package org.apache.iotdb.db.mpp.plan.expression.leaf;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
 import org.apache.iotdb.db.metadata.path.PathDeserializeUtil;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.InputLocation;
 import org.apache.iotdb.db.mpp.transformation.dag.memory.LayerMemoryAssigner;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -90,11 +88,6 @@ public class TimeSeriesOperand extends LeafOperand {
     pathSet.add(path);
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) {
-    return typeProvider.getType(toString());
-  }
-
   @Override
   public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     inputColumnIndex = udtfPlan.getReaderIndexByExpressionName(toString());
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/TimestampOperand.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/TimestampOperand.java
index 076d7594d2..496b599aa9 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/TimestampOperand.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/leaf/TimestampOperand.java
@@ -21,14 +21,12 @@ package org.apache.iotdb.db.mpp.plan.expression.leaf;
 
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.InputLocation;
 import org.apache.iotdb.db.mpp.transformation.dag.memory.LayerMemoryAssigner;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -77,12 +75,6 @@ public class TimestampOperand extends LeafOperand {
     pathSet.add(TIMESTAMP_PARTIAL_PATH);
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) {
-    typeProvider.setType(toString(), TSDataType.INT64);
-    return TSDataType.INT64;
-  }
-
   @Override
   public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     // do nothing
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java
index ca3a83f9b2..197fa1b41e 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/multi/FunctionExpression.java
@@ -23,7 +23,6 @@ import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
-import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
@@ -35,8 +34,6 @@ import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFExecutor;
 import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFInformationInferrer;
 import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
 import org.apache.iotdb.db.qp.strategy.optimizer.ConcatPathOptimizer;
-import org.apache.iotdb.db.utils.TypeInferenceUtils;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 import org.apache.iotdb.udf.api.customizer.strategy.AccessStrategy;
 
@@ -242,42 +239,6 @@ public class FunctionExpression extends Expression {
     expressionName2Executor.put(expressionString, new UDTFExecutor(functionName, zoneId));
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) {
-    final String expressionString = toString();
-
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      for (Expression expression : expressions) {
-        expression.inferTypes(typeProvider);
-      }
-
-      if (!isBuiltInAggregationFunctionExpression()) {
-        typeProvider.setType(
-            expressionString,
-            new UDTFInformationInferrer(functionName)
-                .inferOutputType(
-                    expressions.stream().map(Expression::toString).collect(Collectors.toList()),
-                    expressions.stream()
-                        .map(f -> typeProvider.getType(f.toString()))
-                        .collect(Collectors.toList()),
-                    functionAttributes));
-      } else {
-        if (expressions.size() != 1) {
-          throw new SemanticException(
-              String.format(
-                  "Builtin aggregation function only accepts 1 input expression. Actual %d input expressions.",
-                  expressions.size()));
-        }
-        typeProvider.setType(
-            expressionString,
-            TypeInferenceUtils.getAggrDataType(
-                functionName, typeProvider.getType(expressions.get(0).toString())));
-      }
-    }
-
-    return typeProvider.getType(expressionString);
-  }
-
   @Override
   public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
     for (Expression expression : expressions) {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/BetweenExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/BetweenExpression.java
index 3f3be2e947..62e91a9348 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/BetweenExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/BetweenExpression.java
@@ -21,11 +21,9 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.ternary;
 
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.io.DataOutputStream;
@@ -64,18 +62,6 @@ public class BetweenExpression extends TernaryExpression {
     return "between";
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) {
-    final String expressionString = toString();
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      firstExpression.inferTypes(typeProvider);
-      secondExpression.inferTypes(typeProvider);
-      thirdExpression.inferTypes(typeProvider);
-      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
-    }
-    return TSDataType.BOOLEAN;
-  }
-
   @Override
   protected String getExpressionStringInternal() {
     return firstExpression + " BETWEEN " + secondExpression + " AND " + thirdExpression;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java
index 8de05ba5d7..c9278f632e 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java
@@ -19,14 +19,12 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.unary;
 
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.io.DataOutputStream;
@@ -64,16 +62,6 @@ public class InExpression extends UnaryExpression {
     return values;
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) {
-    final String expressionString = toString();
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      expression.inferTypes(typeProvider);
-      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
-    }
-    return TSDataType.BOOLEAN;
-  }
-
   @Override
   protected String getExpressionStringInternal() {
     StringBuilder stringBuilder = new StringBuilder();
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/IsNullExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/IsNullExpression.java
index 57062b3531..ba6e4a9fcb 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/IsNullExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/IsNullExpression.java
@@ -19,11 +19,9 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.unary;
 
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.io.DataOutputStream;
@@ -47,16 +45,6 @@ public class IsNullExpression extends UnaryExpression {
     return isNot;
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) {
-    final String expressionString = toString();
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      expression.inferTypes(typeProvider);
-      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
-    }
-    return TSDataType.BOOLEAN;
-  }
-
   @Override
   protected String getExpressionStringInternal() {
     return expression + " IS " + (isNot ? "NOT " : "") + "NULL";
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java
index 5d65547011..543af09d2b 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java
@@ -19,12 +19,9 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.unary;
 
-import org.apache.iotdb.db.exception.sql.SemanticException;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.io.DataOutputStream;
@@ -118,17 +115,6 @@ public class LikeExpression extends UnaryExpression {
     return stringBuilder.toString();
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) throws SemanticException {
-    final String expressionString = toString();
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      checkInputExpressionDataType(
-          expression.toString(), expression.inferTypes(typeProvider), TSDataType.TEXT);
-      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
-    }
-    return TSDataType.BOOLEAN;
-  }
-
   @Override
   protected String getExpressionStringInternal() {
     return expression + " LIKE '" + pattern + "'";
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LogicNotExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LogicNotExpression.java
index 05800326ae..00527cd785 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LogicNotExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LogicNotExpression.java
@@ -19,15 +19,12 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.unary;
 
-import org.apache.iotdb.db.exception.sql.SemanticException;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
 
@@ -46,17 +43,6 @@ public class LogicNotExpression extends UnaryExpression {
     return new LogicNotExpression(childExpression);
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) throws SemanticException {
-    final String expressionString = toString();
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      Expression.checkInputExpressionDataType(
-          expression.toString(), expression.inferTypes(typeProvider), TSDataType.BOOLEAN);
-      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
-    }
-    return TSDataType.BOOLEAN;
-  }
-
   @Override
   public String getExpressionStringInternal() {
     return expression instanceof FunctionExpression
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/NegationExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/NegationExpression.java
index 68f902e360..7f279cd626 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/NegationExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/NegationExpression.java
@@ -19,15 +19,12 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.unary;
 
-import org.apache.iotdb.db.exception.sql.SemanticException;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
 
@@ -46,23 +43,6 @@ public class NegationExpression extends UnaryExpression {
     return new NegationExpression(childExpression);
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) throws SemanticException {
-    final String expressionString = toString();
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      TSDataType inputExpressionType = expression.inferTypes(typeProvider);
-      Expression.checkInputExpressionDataType(
-          expression.toString(),
-          inputExpressionType,
-          TSDataType.INT32,
-          TSDataType.INT64,
-          TSDataType.FLOAT,
-          TSDataType.DOUBLE);
-      typeProvider.setType(expressionString, inputExpressionType);
-    }
-    return typeProvider.getType(expressionString);
-  }
-
   @Override
   public String getExpressionStringInternal() {
     return expression instanceof TimeSeriesOperand
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java
index 579ffa0b2c..a67dfb0340 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java
@@ -19,12 +19,9 @@
 
 package org.apache.iotdb.db.mpp.plan.expression.unary;
 
-import org.apache.iotdb.db.exception.sql.SemanticException;
-import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import org.apache.commons.lang3.Validate;
@@ -70,17 +67,6 @@ public class RegularExpression extends UnaryExpression {
     return new RegularExpression(childExpression, patternString, pattern);
   }
 
-  @Override
-  public TSDataType inferTypes(TypeProvider typeProvider) throws SemanticException {
-    final String expressionString = toString();
-    if (!typeProvider.containsTypeInfoOf(expressionString)) {
-      checkInputExpressionDataType(
-          expression.toString(), expression.inferTypes(typeProvider), TSDataType.TEXT);
-      typeProvider.setType(expressionString, TSDataType.BOOLEAN);
-    }
-    return TSDataType.BOOLEAN;
-  }
-
   @Override
   protected String getExpressionStringInternal() {
     return expression + " REGEXP '" + patternString + "'";


[iotdb] 01/07: finish ExpressionTypeAnalyzer

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

hui pushed a commit to branch lmh/TypeProviderOpt
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 13f6ac54a781b19ec3eb4d77ca10b454a45ec681
Author: Minghui Liu <li...@foxmail.com>
AuthorDate: Tue Sep 6 10:52:45 2022 +0800

    finish ExpressionTypeAnalyzer
---
 .../apache/iotdb/db/mpp/plan/analyze/Analysis.java |   4 +
 .../mpp/plan/analyze/ExpressionTypeAnalyzer.java   | 230 ++++++++++++++++++++-
 .../binary/ArithmeticBinaryExpression.java         |   6 +
 .../expression/binary/CompareBinaryExpression.java |   6 +
 .../expression/binary/LogicBinaryExpression.java   |   6 +
 .../plan/expression/ternary/BetweenExpression.java |   6 +-
 .../db/mpp/plan/expression/unary/InExpression.java |   6 +
 .../plan/expression/unary/IsNullExpression.java    |   6 +
 .../mpp/plan/expression/unary/LikeExpression.java  |   6 +
 .../plan/expression/unary/LogicNotExpression.java  |   6 +
 .../plan/expression/unary/NegationExpression.java  |   6 +
 .../plan/expression/unary/RegularExpression.java   |   6 +
 .../plan/expression/visitor/ExpressionVisitor.java |  63 +++++-
 13 files changed, 342 insertions(+), 15 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
index ae27b02122..2e61ba99e5 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
@@ -460,4 +460,8 @@ public class Analysis {
   public void setRelatedTemplateInfo(Map<Integer, Template> relatedTemplateInfo) {
     this.relatedTemplateInfo = relatedTemplateInfo;
   }
+
+  public void addTypes(Map<NodeRef<Expression>, TSDataType> types) {
+    this.expressionTypes.putAll(types);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionTypeAnalyzer.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionTypeAnalyzer.java
index a14103bbf3..98d193dccc 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionTypeAnalyzer.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionTypeAnalyzer.java
@@ -19,36 +19,61 @@
 
 package org.apache.iotdb.db.mpp.plan.analyze;
 
+import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.mpp.common.NodeRef;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.ArithmeticBinaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.CompareBinaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.LogicBinaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimestampOperand;
+import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.InExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.IsNullExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.LikeExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.LogicNotExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.NegationExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.RegularExpression;
 import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
+import org.apache.iotdb.db.mpp.transformation.dag.udf.UDTFInformationInferrer;
+import org.apache.iotdb.db.utils.TypeInferenceUtils;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
+import java.util.Arrays;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
 
 public class ExpressionTypeAnalyzer {
 
   private final Map<NodeRef<Expression>, TSDataType> expressionTypes = new LinkedHashMap<>();
 
-  private ExpressionTypeAnalyzer(Analysis analysis, TypeProvider types) {}
+  private ExpressionTypeAnalyzer() {}
 
   public static void analyzeExpression(Analysis analysis, Expression expression) {
-    ExpressionTypeAnalyzer analyzer = new ExpressionTypeAnalyzer(analysis, TypeProvider.empty());
+    ExpressionTypeAnalyzer analyzer = new ExpressionTypeAnalyzer();
     analyzer.analyze(expression);
 
     updateAnalysis(analysis, analyzer);
   }
 
-  private static void updateAnalysis(Analysis analysis, ExpressionTypeAnalyzer analyzer) {}
+  private static void updateAnalysis(Analysis analysis, ExpressionTypeAnalyzer analyzer) {
+    analysis.addTypes(analyzer.getExpressionTypes());
+  }
 
   public TSDataType analyze(Expression expression) {
     Visitor visitor = new Visitor();
     return visitor.process(expression, null);
   }
 
+  public Map<NodeRef<Expression>, TSDataType> getExpressionTypes() {
+    return expressionTypes;
+  }
+
   private class Visitor extends ExpressionVisitor<TSDataType, Void> {
 
     @Override
@@ -63,21 +88,206 @@ public class ExpressionTypeAnalyzer {
 
     @Override
     public TSDataType visitExpression(Expression expression, Void context) {
-        throw new UnsupportedOperationException(
-                "Unsupported expression type: " + expression.getClass().getName());
+      throw new UnsupportedOperationException(
+          "Unsupported expression type: " + expression.getClass().getName());
     }
 
     @Override
-    public TSDataType visitTimeSeriesOperand(TimeSeriesOperand timeSeriesOperand, Void context) {
-      expressionTypes.put(NodeRef.of(timeSeriesOperand), TSDataType.INT64);
-      return timeSeriesOperand.getPath().getSeriesType();
+    public TSDataType visitInExpression(InExpression inExpression, Void context) {
+      process(inExpression.getExpression(), null);
+      return setExpressionType(inExpression, TSDataType.BOOLEAN);
+    }
+
+    @Override
+    public TSDataType visitIsNullExpression(IsNullExpression isNullExpression, Void context) {
+      process(isNullExpression.getExpression(), null);
+      return setExpressionType(isNullExpression, TSDataType.BOOLEAN);
+    }
+
+    @Override
+    public TSDataType visitLikeExpression(LikeExpression likeExpression, Void context) {
+      checkInputExpressionDataType(
+          likeExpression.getExpression().toString(),
+          process(likeExpression.getExpression(), null),
+          TSDataType.TEXT);
+      return setExpressionType(likeExpression, TSDataType.BOOLEAN);
+    }
+
+    @Override
+    public TSDataType visitRegularExpression(RegularExpression regularExpression, Void context) {
+      checkInputExpressionDataType(
+          regularExpression.getExpression().toString(),
+          process(regularExpression.getExpression(), null),
+          TSDataType.TEXT);
+      return setExpressionType(regularExpression, TSDataType.BOOLEAN);
+    }
+
+    @Override
+    public TSDataType visitLogicNotExpression(LogicNotExpression logicNotExpression, Void context) {
+      checkInputExpressionDataType(
+          logicNotExpression.getExpression().toString(),
+          process(logicNotExpression.getExpression(), null),
+          TSDataType.BOOLEAN);
+      return setExpressionType(logicNotExpression, TSDataType.BOOLEAN);
+    }
+
+    @Override
+    public TSDataType visitNegationExpression(NegationExpression negationExpression, Void context) {
+      TSDataType inputExpressionType = process(negationExpression.getExpression(), null);
+      checkInputExpressionDataType(
+          negationExpression.getExpression().toString(),
+          inputExpressionType,
+          TSDataType.INT32,
+          TSDataType.INT64,
+          TSDataType.FLOAT,
+          TSDataType.DOUBLE);
+      return setExpressionType(negationExpression, inputExpressionType);
+    }
+
+    @Override
+    public TSDataType visitArithmeticBinaryExpression(
+        ArithmeticBinaryExpression arithmeticBinaryExpression, Void context) {
+      checkInputExpressionDataType(
+          arithmeticBinaryExpression.getLeftExpression().toString(),
+          process(arithmeticBinaryExpression.getLeftExpression(), null),
+          TSDataType.INT32,
+          TSDataType.INT64,
+          TSDataType.FLOAT,
+          TSDataType.DOUBLE);
+      checkInputExpressionDataType(
+          arithmeticBinaryExpression.getRightExpression().toString(),
+          process(arithmeticBinaryExpression.getRightExpression(), null),
+          TSDataType.INT32,
+          TSDataType.INT64,
+          TSDataType.FLOAT,
+          TSDataType.DOUBLE);
+      return setExpressionType(arithmeticBinaryExpression, TSDataType.DOUBLE);
+    }
+
+    @Override
+    public TSDataType visitLogicBinaryExpression(
+        LogicBinaryExpression logicBinaryExpression, Void context) {
+      checkInputExpressionDataType(
+          logicBinaryExpression.getLeftExpression().toString(),
+          process(logicBinaryExpression.getLeftExpression(), null),
+          TSDataType.BOOLEAN);
+      checkInputExpressionDataType(
+          logicBinaryExpression.getRightExpression().toString(),
+          process(logicBinaryExpression.getRightExpression(), null),
+          TSDataType.BOOLEAN);
+      return setExpressionType(logicBinaryExpression, TSDataType.BOOLEAN);
+    }
+
+    @Override
+    public TSDataType visitCompareBinaryExpression(
+        CompareBinaryExpression compareBinaryExpression, Void context) {
+      final TSDataType leftExpressionDataType =
+          process(compareBinaryExpression.getLeftExpression(), null);
+      final TSDataType rightExpressionDataType =
+          process(compareBinaryExpression.getRightExpression(), null);
+
+      if (!leftExpressionDataType.equals(rightExpressionDataType)) {
+        final String leftExpressionString = compareBinaryExpression.getLeftExpression().toString();
+        final String rightExpressionString =
+            compareBinaryExpression.getRightExpression().toString();
+
+        if (TSDataType.BOOLEAN.equals(leftExpressionDataType)
+            || TSDataType.BOOLEAN.equals(rightExpressionDataType)) {
+          checkInputExpressionDataType(
+              leftExpressionString, leftExpressionDataType, TSDataType.BOOLEAN);
+          checkInputExpressionDataType(
+              rightExpressionString, rightExpressionDataType, TSDataType.BOOLEAN);
+        } else if (TSDataType.TEXT.equals(leftExpressionDataType)
+            || TSDataType.TEXT.equals(rightExpressionDataType)) {
+          checkInputExpressionDataType(
+              leftExpressionString, leftExpressionDataType, TSDataType.TEXT);
+          checkInputExpressionDataType(
+              rightExpressionString, rightExpressionDataType, TSDataType.TEXT);
+        } else {
+          checkInputExpressionDataType(
+              leftExpressionString,
+              leftExpressionDataType,
+              TSDataType.INT32,
+              TSDataType.INT64,
+              TSDataType.FLOAT,
+              TSDataType.DOUBLE);
+          checkInputExpressionDataType(
+              rightExpressionString,
+              rightExpressionDataType,
+              TSDataType.INT32,
+              TSDataType.INT64,
+              TSDataType.FLOAT,
+              TSDataType.DOUBLE);
+        }
+      }
+
+      return setExpressionType(compareBinaryExpression, TSDataType.BOOLEAN);
+    }
+
+    @Override
+    public TSDataType visitFunctionExpression(FunctionExpression functionExpression, Void context) {
+      List<Expression> inputExpressions = functionExpression.getExpressions();
+      for (Expression expression : inputExpressions) {
+        process(expression, null);
+      }
+
+      if (functionExpression.isBuiltInAggregationFunctionExpression()) {
+        checkArgument(
+            inputExpressions.size() == 1,
+            String.format(
+                "Builtin aggregation function only accepts 1 input expression. Actual %d input expressions.",
+                inputExpressions.size()));
+        return setExpressionType(
+            functionExpression,
+            TypeInferenceUtils.getAggrDataType(
+                functionExpression.getFunctionName(),
+                expressionTypes.get(NodeRef.of(inputExpressions.get(0)))));
+      } else {
+        return setExpressionType(
+            functionExpression,
+            new UDTFInformationInferrer(functionExpression.getFunctionName())
+                .inferOutputType(
+                    inputExpressions.stream()
+                        .map(Expression::toString)
+                        .collect(Collectors.toList()),
+                    inputExpressions.stream()
+                        .map(f -> expressionTypes.get(NodeRef.of(f)))
+                        .collect(Collectors.toList()),
+                    functionExpression.getFunctionAttributes()));
+      }
     }
 
     @Override
     public TSDataType visitTimeStampOperand(TimestampOperand timestampOperand, Void context) {
-      expressionTypes.put(NodeRef.of(timestampOperand), TSDataType.INT64);
-      return TSDataType.INT64;
+      return setExpressionType(timestampOperand, TSDataType.INT64);
+    }
+
+    @Override
+    public TSDataType visitTimeSeriesOperand(TimeSeriesOperand timeSeriesOperand, Void context) {
+      return setExpressionType(timeSeriesOperand, timeSeriesOperand.getPath().getSeriesType());
+    }
+
+    @Override
+    public TSDataType visitConstantOperand(ConstantOperand constantOperand, Void context) {
+      return setExpressionType(constantOperand, constantOperand.getDataType());
+    }
+
+    private TSDataType setExpressionType(Expression expression, TSDataType type) {
+      expressionTypes.put(NodeRef.of(expression), type);
+      return type;
     }
 
+    private void checkInputExpressionDataType(
+        String expressionString, TSDataType actual, TSDataType... expected) {
+      for (TSDataType type : expected) {
+        if (actual.equals(type)) {
+          return;
+        }
+      }
+      throw new SemanticException(
+          String.format(
+              "Invalid input expression data type. expression: %s, actual data type: %s, expected data type(s): %s.",
+              expressionString, actual.name(), Arrays.toString(expected)));
+    }
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/ArithmeticBinaryExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/ArithmeticBinaryExpression.java
index 3fdd5659a9..cb7d7eacec 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/ArithmeticBinaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/ArithmeticBinaryExpression.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.mpp.plan.expression.binary;
 
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
@@ -57,4 +58,9 @@ public abstract class ArithmeticBinaryExpression extends BinaryExpression {
     }
     return TSDataType.DOUBLE;
   }
+
+  @Override
+  public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+    return visitor.visitArithmeticBinaryExpression(this, context);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/CompareBinaryExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/CompareBinaryExpression.java
index ff7032af3d..850d89b3df 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/CompareBinaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/CompareBinaryExpression.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.mpp.plan.expression.binary;
 
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
@@ -87,4 +88,9 @@ public abstract class CompareBinaryExpression extends BinaryExpression {
   public boolean isCompareBinaryExpression() {
     return true;
   }
+
+  @Override
+  public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+    return visitor.visitCompareBinaryExpression(this, context);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/LogicBinaryExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/LogicBinaryExpression.java
index b4d644f681..05bcd06fd2 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/LogicBinaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/binary/LogicBinaryExpression.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.mpp.plan.expression.binary;
 
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
@@ -47,4 +48,9 @@ public abstract class LogicBinaryExpression extends BinaryExpression {
     }
     return TSDataType.BOOLEAN;
   }
+
+  @Override
+  public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+    return visitor.visitLogicBinaryExpression(this, context);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/BetweenExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/BetweenExpression.java
index 2b6f9c79e3..3f3be2e947 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/BetweenExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ternary/BetweenExpression.java
@@ -24,6 +24,7 @@ package org.apache.iotdb.db.mpp.plan.expression.ternary;
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
@@ -96,7 +97,8 @@ public class BetweenExpression extends TernaryExpression {
     ReadWriteIOUtils.write(isNotBetween, stream);
   }
 
-  public Expression getExpression() {
-    return this;
+  @Override
+  public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+    return visitor.visitBetweenExpression(this, context);
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java
index 8dde1583a1..8de05ba5d7 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
@@ -123,4 +124,9 @@ public class InExpression extends UnaryExpression {
       ReadWriteIOUtils.write(value, stream);
     }
   }
+
+  @Override
+  public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+    return visitor.visitInExpression(this, context);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/IsNullExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/IsNullExpression.java
index 2a862e2f75..57062b3531 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/IsNullExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/IsNullExpression.java
@@ -22,6 +22,7 @@ package org.apache.iotdb.db.mpp.plan.expression.unary;
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
@@ -82,4 +83,9 @@ public class IsNullExpression extends UnaryExpression {
     super.serialize(stream);
     ReadWriteIOUtils.write(isNot, stream);
   }
+
+  @Override
+  public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+    return visitor.visitIsNullExpression(this, context);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java
index 004b56c507..5d65547011 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
@@ -154,4 +155,9 @@ public class LikeExpression extends UnaryExpression {
     super.serialize(stream);
     ReadWriteIOUtils.write(patternString, stream);
   }
+
+  @Override
+  public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+    return visitor.visitLikeExpression(this, context);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LogicNotExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LogicNotExpression.java
index c1b1a7f5ef..05800326ae 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LogicNotExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LogicNotExpression.java
@@ -26,6 +26,7 @@ import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
@@ -69,4 +70,9 @@ public class LogicNotExpression extends UnaryExpression {
   public ExpressionType getExpressionType() {
     return ExpressionType.LOGIC_NOT;
   }
+
+  @Override
+  public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+    return visitor.visitLogicNotExpression(this, context);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/NegationExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/NegationExpression.java
index 30473ddeac..68f902e360 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/NegationExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/NegationExpression.java
@@ -26,6 +26,7 @@ import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import java.nio.ByteBuffer;
@@ -76,4 +77,9 @@ public class NegationExpression extends UnaryExpression {
   public ExpressionType getExpressionType() {
     return ExpressionType.NEGATION;
   }
+
+  @Override
+  public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+    return visitor.visitNegationExpression(this, context);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java
index 7759b29f68..579ffa0b2c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
+import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionVisitor;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
@@ -101,4 +102,9 @@ public class RegularExpression extends UnaryExpression {
     super.serialize(stream);
     ReadWriteIOUtils.write(patternString, stream);
   }
+
+  @Override
+  public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+    return visitor.visitRegularExpression(this, context);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionVisitor.java
index a210c13c16..7ebc074a99 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionVisitor.java
@@ -20,12 +20,23 @@
 package org.apache.iotdb.db.mpp.plan.expression.visitor;
 
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.ArithmeticBinaryExpression;
 import org.apache.iotdb.db.mpp.plan.expression.binary.BinaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.CompareBinaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.binary.LogicBinaryExpression;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.LeafOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimestampOperand;
 import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
+import org.apache.iotdb.db.mpp.plan.expression.ternary.BetweenExpression;
 import org.apache.iotdb.db.mpp.plan.expression.ternary.TernaryExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.InExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.IsNullExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.LikeExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.LogicNotExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.NegationExpression;
+import org.apache.iotdb.db.mpp.plan.expression.unary.RegularExpression;
 import org.apache.iotdb.db.mpp.plan.expression.unary.UnaryExpression;
 
 /**
@@ -47,27 +58,73 @@ public abstract class ExpressionVisitor<R, C> {
     return visitExpression(unaryExpression, context);
   }
 
+  public R visitInExpression(InExpression inExpression, C context) {
+    return visitUnaryExpression(inExpression, context);
+  }
+
+  public R visitIsNullExpression(IsNullExpression isNullExpression, C context) {
+    return visitUnaryExpression(isNullExpression, context);
+  }
+
+  public R visitLikeExpression(LikeExpression likeExpression, C context) {
+    return visitUnaryExpression(likeExpression, context);
+  }
+
+  public R visitRegularExpression(RegularExpression regularExpression, C context) {
+    return visitUnaryExpression(regularExpression, context);
+  }
+
+  public R visitLogicNotExpression(LogicNotExpression logicNotExpression, C context) {
+    return visitUnaryExpression(logicNotExpression, context);
+  }
+
+  public R visitNegationExpression(NegationExpression negationExpression, C context) {
+    return visitUnaryExpression(negationExpression, context);
+  }
+
   public R visitBinaryExpression(BinaryExpression binaryExpression, C context) {
     return visitExpression(binaryExpression, context);
   }
 
+  public R visitArithmeticBinaryExpression(
+      ArithmeticBinaryExpression arithmeticBinaryExpression, C context) {
+    return visitBinaryExpression(arithmeticBinaryExpression, context);
+  }
+
+  public R visitLogicBinaryExpression(LogicBinaryExpression logicBinaryExpression, C context) {
+    return visitBinaryExpression(logicBinaryExpression, context);
+  }
+
+  public R visitCompareBinaryExpression(
+      CompareBinaryExpression compareBinaryExpression, C context) {
+    return visitBinaryExpression(compareBinaryExpression, context);
+  }
+
   public R visitTernaryExpression(TernaryExpression ternaryExpression, C context) {
     return visitExpression(ternaryExpression, context);
   }
 
+  public R visitBetweenExpression(BetweenExpression betweenExpression, C context) {
+    return visitTernaryExpression(betweenExpression, context);
+  }
+
   public R visitFunctionExpression(FunctionExpression functionExpression, C context) {
     return visitExpression(functionExpression, context);
   }
 
+  public R visitLeafOperand(LeafOperand leafOperand, C context) {
+    return visitExpression(leafOperand, context);
+  }
+
   public R visitTimeStampOperand(TimestampOperand timestampOperand, C context) {
-    return visitExpression(timestampOperand, context);
+    return visitLeafOperand(timestampOperand, context);
   }
 
   public R visitTimeSeriesOperand(TimeSeriesOperand timeSeriesOperand, C context) {
-    return visitExpression(timeSeriesOperand, context);
+    return visitLeafOperand(timeSeriesOperand, context);
   }
 
   public R visitConstantOperand(ConstantOperand constantOperand, C context) {
-    return visitExpression(constantOperand, context);
+    return visitLeafOperand(constantOperand, context);
   }
 }


[iotdb] 07/07: bug fix

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

hui pushed a commit to branch lmh/TypeProviderOpt
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 17dbab6890cb6b42806c00bdd4b06894a176cc1f
Author: Minghui Liu <li...@foxmail.com>
AuthorDate: Wed Sep 7 18:36:39 2022 +0800

    bug fix
---
 .../db/mpp/plan/planner/SubPlanTypeExtractor.java   | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java
index 0c78183794..be33a8000a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java
@@ -19,9 +19,12 @@
 
 package org.apache.iotdb.db.mpp.plan.planner;
 
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.SimplePlanVisitor;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.source.AlignedSeriesAggregationScanNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.source.SeriesAggregationScanNode;
 
 public class SubPlanTypeExtractor {
 
@@ -50,5 +53,23 @@ public class SubPlanTypeExtractor {
       }
       return null;
     }
+
+    @Override
+    public Void visitSeriesAggregationScan(SeriesAggregationScanNode node, Void context) {
+      String sourcePath = node.getSeriesPath().getFullPath();
+      typeProvider.setType(sourcePath, allTypes.getType(sourcePath));
+      return visitPlan(node, context);
+    }
+
+    @Override
+    public Void visitAlignedSeriesAggregationScan(
+        AlignedSeriesAggregationScanNode node, Void context) {
+      AlignedPath alignedPath = node.getAlignedPath();
+      for (int i = 0; i < alignedPath.getColumnNum(); i++) {
+        String sourcePath = alignedPath.getPathWithMeasurement(i).getFullPath();
+        typeProvider.setType(sourcePath, allTypes.getType(sourcePath));
+      }
+      return visitPlan(node, context);
+    }
   }
 }