This is an automated email from the ASF dual-hosted git repository. hui pushed a commit to branch lmh/FixGroupByLevelHeader in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit d69208519da0390330f54e0d92051bede3b182ce Author: Minghui Liu <[email protected]> AuthorDate: Tue Jul 26 14:29:41 2022 +0800 fix incorrect column name in some scenarios for group by level query --- .../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java | 89 ++++++++++++++-------- .../db/mpp/plan/analyze/ExpressionAnalyzer.java | 8 +- 2 files changed, 62 insertions(+), 35 deletions(-) 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 9279c0ae31..c36085b9f5 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 @@ -415,11 +415,12 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> private List<Pair<Expression, String>> analyzeSelect( QueryStatement queryStatement, SchemaTree schemaTree) { List<Pair<Expression, String>> outputExpressions = new ArrayList<>(); + boolean isGroupByLevel = queryStatement.isGroupByLevel(); ColumnPaginationController paginationController = new ColumnPaginationController( queryStatement.getSeriesLimit(), queryStatement.getSeriesOffset(), - queryStatement.isLastQuery() || queryStatement.isGroupByLevel()); + queryStatement.isLastQuery() || isGroupByLevel); for (ResultColumn resultColumn : queryStatement.getSelectComponent().getResultColumns()) { boolean hasAlias = resultColumn.hasAlias(); @@ -436,22 +437,28 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> continue; } if (paginationController.hasCurLimit()) { - Expression expressionWithoutAlias = - ExpressionAnalyzer.removeAliasFromExpression(expression); - String alias = - !Objects.equals(expressionWithoutAlias, expression) - ? expression.getExpressionString() - : null; - alias = hasAlias ? resultColumn.getAlias() : alias; - outputExpressions.add(new Pair<>(expressionWithoutAlias, alias)); - if (queryStatement.isGroupByLevel() - && resultColumn.getExpression() instanceof FunctionExpression) { - queryStatement - .getGroupByLevelComponent() - .updateIsCountStar((FunctionExpression) resultColumn.getExpression()); + if (isGroupByLevel) { + ExpressionAnalyzer.updateTypeProvider(expression, typeProvider); + expression.inferTypes(typeProvider); + outputExpressions.add(new Pair<>(expression, resultColumn.getAlias())); + if (resultColumn.getExpression() instanceof FunctionExpression) { + queryStatement + .getGroupByLevelComponent() + .updateIsCountStar((FunctionExpression) resultColumn.getExpression()); + } + } else { + Expression expressionWithoutAlias = + ExpressionAnalyzer.removeAliasFromExpression(expression); + String alias = + !Objects.equals(expressionWithoutAlias, expression) + ? expression.getExpressionString() + : null; + alias = hasAlias ? resultColumn.getAlias() : alias; + + ExpressionAnalyzer.updateTypeProvider(expressionWithoutAlias, typeProvider); + expressionWithoutAlias.inferTypes(typeProvider); + outputExpressions.add(new Pair<>(expressionWithoutAlias, alias)); } - ExpressionAnalyzer.updateTypeProvider(expressionWithoutAlias, typeProvider); - expressionWithoutAlias.inferTypes(typeProvider); paginationController.consumeLimit(); } else { break; @@ -662,6 +669,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> rawPathToGroupedPathMap.putAll(groupByLevelController.getRawPathToGroupedPathMap()); Map<Expression, Set<Expression>> groupByLevelExpressions = new LinkedHashMap<>(); + outputExpressions.clear(); ColumnPaginationController paginationController = new ColumnPaginationController( queryStatement.getSeriesLimit(), queryStatement.getSeriesOffset(), false); @@ -671,34 +679,51 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> continue; } if (paginationController.hasCurLimit()) { - groupByLevelExpressions.put( - groupedExpression, rawGroupByLevelExpressions.get(groupedExpression)); + Pair<Expression, String> outputExpression = + removeAliasFromExpression( + groupedExpression, + groupByLevelController.getAlias(groupedExpression.getExpressionString())); + Expression groupedExpressionWithoutAlias = outputExpression.left; + Set<Expression> rawExpressionsWithoutAlias = + rawGroupByLevelExpressions.get(groupedExpression).stream() + .map(ExpressionAnalyzer::removeAliasFromExpression) + .collect(Collectors.toSet()); + rawExpressionsWithoutAlias.forEach(expression -> expression.inferTypes(typeProvider)); + + 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); + outputExpressions.add(outputExpression); paginationController.consumeLimit(); } else { break; } } - // reset outputExpressions & transformExpressions after applying SLIMIT/SOFFSET - outputExpressions.clear(); - for (Expression groupedExpression : groupByLevelExpressions.keySet()) { - TSDataType dataType = - typeProvider.getType( - new ArrayList<>(groupByLevelExpressions.get(groupedExpression)) - .get(0) - .getExpressionString()); - typeProvider.setType(groupedExpression.getExpressionString(), dataType); - outputExpressions.add( - new Pair<>( - groupedExpression, - groupByLevelController.getAlias(groupedExpression.getExpressionString()))); - } + // reset transformExpressions after applying SLIMIT/SOFFSET transformExpressions.clear(); transformExpressions.addAll( groupByLevelExpressions.values().stream().flatMap(Set::stream).collect(Collectors.toSet())); return groupByLevelExpressions; } + private Pair<Expression, String> removeAliasFromExpression( + Expression rawExpression, String rawAlias) { + Expression expressionWithoutAlias = ExpressionAnalyzer.removeAliasFromExpression(rawExpression); + String alias = + !Objects.equals(expressionWithoutAlias, rawExpression) + ? rawExpression.getExpressionString() + : null; + alias = rawAlias == null ? alias : rawAlias; + return new Pair<>(expressionWithoutAlias, alias); + } + private DatasetHeader analyzeOutput( QueryStatement queryStatement, List<Pair<Expression, String>> outputExpressions) { boolean isIgnoreTimestamp = 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 3569ba75f1..d3766a47cc 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 @@ -968,10 +968,12 @@ public class ExpressionAnalyzer { functionExpression.getFunctionAttributes(), childExpressions); } else if (expression instanceof TimeSeriesOperand) { - MeasurementPath rawPath = (MeasurementPath) ((TimeSeriesOperand) expression).getPath(); + PartialPath rawPath = ((TimeSeriesOperand) expression).getPath(); if (rawPath.isMeasurementAliasExists()) { - MeasurementPath newPath = new MeasurementPath(rawPath, rawPath.getMeasurementSchema()); - newPath.setUnderAlignedEntity(rawPath.isUnderAlignedEntity()); + MeasurementPath measurementPath = (MeasurementPath) rawPath; + MeasurementPath newPath = + new MeasurementPath(measurementPath, measurementPath.getMeasurementSchema()); + newPath.setUnderAlignedEntity(measurementPath.isUnderAlignedEntity()); return new TimeSeriesOperand(newPath); } return expression;
