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 <[email protected]>
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)));

Reply via email to