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:19 UTC
[iotdb] 03/07: add SymbolAllocator
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)));