This is an automated email from the ASF dual-hosted git repository. xiangweiwei pushed a commit to branch groupByLevelBug in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit a009b3354f11cd9e401a9a3eae5bad6be0dc89c7 Author: Alima777 <[email protected]> AuthorDate: Thu Jun 9 15:12:53 2022 +0800 Fix the datatype consistency check of group by level --- .../apache/iotdb/db/mpp/plan/analyze/Analyzer.java | 16 ------------ .../mpp/plan/analyze/GroupByLevelController.java | 29 +++++++++++++++++++--- 2 files changed, 25 insertions(+), 20 deletions(-) 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 8d76c19387..834ee25932 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 @@ -674,9 +674,6 @@ public class Analyzer { Map<Expression, Set<Expression>> rawGroupByLevelExpressions = groupByLevelController.getGroupedPathMap(); rawPathToGroupedPathMap.putAll(groupByLevelController.getRawPathToGroupedPathMap()); - // check whether the datatype of paths which has the same output column name are consistent - // if not, throw a SemanticException - rawGroupByLevelExpressions.values().forEach(this::checkDataTypeConsistencyInGroupByLevel); Map<Expression, Set<Expression>> groupByLevelExpressions = new LinkedHashMap<>(); ColumnPaginationController paginationController = @@ -857,19 +854,6 @@ public class Analyzer { } } - /** Check datatype consistency in GROUP BY LEVEL. */ - private void checkDataTypeConsistencyInGroupByLevel(Set<Expression> expressions) { - List<Expression> expressionList = new ArrayList<>(expressions); - TSDataType checkedDataType = - typeProvider.getType(expressionList.get(0).getExpressionString()); - for (Expression expression : expressionList) { - if (typeProvider.getType(expression.getExpressionString()) != checkedDataType) { - throw new SemanticException( - "GROUP BY LEVEL: the data types of the same output column should be the same."); - } - } - } - private void checkDataTypeConsistencyInFill(Expression fillColumn, Literal fillValue) { TSDataType checkedDataType = typeProvider.getType(fillColumn.getExpressionString()); if (!fillValue.isDataTypeConsistency(checkedDataType)) { 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 a13353518e..f3fd875285 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 @@ -26,6 +26,7 @@ import org.apache.iotdb.db.exception.sql.StatementAnalyzeException; 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.db.utils.TypeInferenceUtils; import java.util.ArrayList; import java.util.Collections; @@ -46,10 +47,10 @@ public class GroupByLevelController { private final int[] levels; - /** count(root.sg.d1.s1) with level = 1 -> { count(root.*.d1.s1) : count(root.d1.d1.s1) } */ + /** count(root.sg.d1.s1) with level = 1 -> { count(root.*.d1.s1) : count(root.sg.d1.s1) } */ private final Map<Expression, Set<Expression>> groupedPathMap; - /** count(root.sg.d1.s1) with level = 1 -> { root.d1.d1.s1 : root.d1.*.s1 } */ + /** count(root.sg.d1.s1) with level = 1 -> { root.sg.d1.s1 : root.sg.*.s1 } */ private final Map<Expression, Expression> rawPathToGroupedPathMap; /** count(root.*.d1.s1) -> alias */ @@ -80,7 +81,6 @@ public class GroupByLevelController { PartialPath rawPath = ((TimeSeriesOperand) expression.getExpressions().get(0)).getPath(); PartialPath groupedPath = generatePartialPathByLevel(rawPath.getNodes(), levels); - typeProvider.setType(groupedPath.getFullPath(), rawPath.getSeriesType()); Expression rawPathExpression = new TimeSeriesOperand(rawPath); Expression groupedPathExpression = new TimeSeriesOperand(groupedPath); @@ -88,11 +88,12 @@ public class GroupByLevelController { rawPathToGroupedPathMap.put(rawPathExpression, groupedPathExpression); } - Expression groupedExpression = + FunctionExpression groupedExpression = new FunctionExpression( ((FunctionExpression) expression).getFunctionName(), ((FunctionExpression) expression).getFunctionAttributes(), Collections.singletonList(groupedPathExpression)); + checkDatatypeConsistency(groupedExpression, rawPath); groupedPathMap.computeIfAbsent(groupedExpression, key -> new HashSet<>()).add(expression); if (alias != null) { @@ -100,6 +101,26 @@ public class GroupByLevelController { } } + /** + * For example, calculating the first_value, + * + * @param expression grouped expression, e.g. count(root.*.d1.s1) + * @param rawPath raw series path, e.g. root.sg.d1.s1 + */ + private void checkDatatypeConsistency(FunctionExpression expression, PartialPath rawPath) { + try { + typeProvider.setType( + expression.getExpressionString(), + TypeInferenceUtils.getAggrDataType( + expression.getFunctionName(), rawPath.getSeriesType())); + } catch (StatementAnalyzeException e) { + throw new SemanticException( + String.format( + "GROUP BY LEVEL: the data types of the same output column[%s] should be the same.", + expression.getExpressionString())); + } + } + private void checkAliasAndUpdateAliasMap(String alias, String groupedExpressionString) throws StatementAnalyzeException { // If an alias is corresponding to more than one result column, throw an exception
