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/12/15 14:38:13 UTC
[iotdb] 03/04: refactor analyze groupByTag
This is an automated email from the ASF dual-hosted git repository.
hui pushed a commit to branch lmh/modifySchemaTreeInterface
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 71ad1571ac49cd5a1e6d23a621295ebf84022dac
Author: Minghui Liu <li...@foxmail.com>
AuthorDate: Thu Dec 15 22:22:59 2022 +0800
refactor analyze groupByTag
---
.../apache/iotdb/db/mpp/plan/analyze/Analysis.java | 8 ---
.../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java | 70 +++++++++-------------
.../db/mpp/plan/analyze/ExpressionAnalyzer.java | 1 +
.../db/mpp/plan/statement/crud/QueryStatement.java | 15 ++++-
4 files changed, 43 insertions(+), 51 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 4b08a15181..2b4ad26216 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
@@ -36,7 +36,6 @@ import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.GroupByTimeParameter;
import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.IntoPathDescriptor;
import org.apache.iotdb.db.mpp.plan.planner.plan.parameter.OrderByParameter;
import org.apache.iotdb.db.mpp.plan.statement.Statement;
-import org.apache.iotdb.db.mpp.plan.statement.crud.QueryStatement;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.read.filter.basic.Filter;
import org.apache.iotdb.tsfile.utils.Pair;
@@ -258,13 +257,6 @@ public class Analysis {
return type;
}
- public boolean hasDataSource() {
- return (dataPartition != null && !dataPartition.isEmpty())
- || (schemaPartition != null && !schemaPartition.isEmpty())
- || (statement instanceof QueryStatement
- && ((QueryStatement) statement).isAggregationQuery());
- }
-
public LinkedHashMap<Expression, Set<Expression>> getCrossGroupByExpressions() {
return crossGroupByExpressions;
}
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 469c6b5f6a..5bcffe3b7e 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
@@ -266,11 +266,15 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
} else {
Map<Integer, List<Pair<Expression, String>>> outputExpressionMap =
analyzeSelect(analysis, queryStatement, schemaTree);
+
outputExpressions = new ArrayList<>();
outputExpressionMap.values().forEach(outputExpressions::addAll);
+
analyzeHaving(analysis, queryStatement, schemaTree);
+
analyzeGroupByLevel(analysis, queryStatement, outputExpressionMap, outputExpressions);
- analyzeGroupByTag(analysis, queryStatement, outputExpressions, schemaTree);
+ analyzeGroupByTag(analysis, queryStatement, outputExpressions);
+
Set<Expression> selectExpressions =
outputExpressions.stream()
.map(Pair::getLeft)
@@ -729,61 +733,43 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
private void analyzeGroupByTag(
Analysis analysis,
QueryStatement queryStatement,
- List<Pair<Expression, String>> outputExpressions,
- ISchemaTree schemaTree) {
+ List<Pair<Expression, String>> outputExpressions) {
if (!queryStatement.isGroupByTag()) {
return;
}
if (analysis.hasValueFilter()) {
throw new SemanticException("Only time filters are supported in GROUP BY TAGS query");
}
+
+ List<String> tagKeys = queryStatement.getGroupByTagComponent().getTagKeys();
Map<List<String>, LinkedHashMap<Expression, List<Expression>>>
tagValuesToGroupedTimeseriesOperands = new HashMap<>();
- LinkedHashMap<Expression, Set<Expression>> groupByTagOutputExpressions = new LinkedHashMap<>();
- List<String> tagKeys = queryStatement.getGroupByTagComponent().getTagKeys();
- List<MeasurementPath> allSelectedPath = schemaTree.getAllMeasurement();
- Map<MeasurementPath, Map<String, String>> queriedTagMap = new HashMap<>();
- allSelectedPath.forEach(v -> queriedTagMap.put(v, v.getTagMap()));
+ LinkedHashMap<Expression, Set<Expression>> outputExpressionToRawExpressionsMap =
+ new LinkedHashMap<>();
for (Pair<Expression, String> outputExpressionAndAlias : outputExpressions) {
- if (!(outputExpressionAndAlias.getLeft() instanceof FunctionExpression
- && outputExpressionAndAlias.getLeft().getExpressions().get(0) instanceof TimeSeriesOperand
- && outputExpressionAndAlias.getLeft().isBuiltInAggregationFunctionExpression())) {
- throw new SemanticException(
- outputExpressionAndAlias.getLeft()
- + " can't be used in group by tag. It will be supported in the future.");
- }
- FunctionExpression outputExpression = (FunctionExpression) outputExpressionAndAlias.getLeft();
- MeasurementPath measurementPath =
- (MeasurementPath)
- ((TimeSeriesOperand) outputExpression.getExpressions().get(0)).getPath();
- MeasurementPath fakePath = null;
- try {
- fakePath =
- new MeasurementPath(measurementPath.getMeasurement(), measurementPath.getSeriesType());
- } catch (IllegalPathException e) {
- // do nothing
- }
- Expression measurementExpression = new TimeSeriesOperand(fakePath);
- Expression groupedExpression =
- new FunctionExpression(
- outputExpression.getFunctionName(),
- outputExpression.getFunctionAttributes(),
- Collections.singletonList(measurementExpression));
- groupByTagOutputExpressions
- .computeIfAbsent(groupedExpression, v -> new HashSet<>())
- .add(outputExpression);
- Map<String, String> tagMap = queriedTagMap.get(measurementPath);
+ FunctionExpression rawExpression = (FunctionExpression) outputExpressionAndAlias.getLeft();
+ FunctionExpression measurementExpression =
+ (FunctionExpression) ExpressionAnalyzer.getMeasurementExpression(rawExpression);
+ outputExpressionToRawExpressionsMap
+ .computeIfAbsent(measurementExpression, v -> new HashSet<>())
+ .add(rawExpression);
+
+ Map<String, String> tagMap =
+ ((MeasurementPath)
+ ((TimeSeriesOperand) measurementExpression.getExpressions().get(0)).getPath())
+ .getTagMap();
List<String> tagValues = new ArrayList<>();
for (String tagKey : tagKeys) {
tagValues.add(tagMap.get(tagKey));
}
tagValuesToGroupedTimeseriesOperands
.computeIfAbsent(tagValues, key -> new LinkedHashMap<>())
- .computeIfAbsent(groupedExpression, key -> new ArrayList<>())
- .add(outputExpression.getExpressions().get(0));
+ .computeIfAbsent(measurementExpression, key -> new ArrayList<>())
+ .add(rawExpression.getExpressions().get(0));
}
+ // update outputExpressions
outputExpressions.clear();
for (String tagKey : tagKeys) {
Expression tagKeyExpression =
@@ -791,14 +777,14 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext>
analyzeExpression(analysis, tagKeyExpression);
outputExpressions.add(new Pair<>(tagKeyExpression, null));
}
- for (Expression groupByTagOutputExpression : groupByTagOutputExpressions.keySet()) {
+ for (Expression outputExpression : outputExpressionToRawExpressionsMap.keySet()) {
// TODO: support alias
- analyzeExpression(analysis, groupByTagOutputExpression);
- outputExpressions.add(new Pair<>(groupByTagOutputExpression, null));
+ analyzeExpression(analysis, outputExpression);
+ outputExpressions.add(new Pair<>(outputExpression, null));
}
analysis.setTagKeys(queryStatement.getGroupByTagComponent().getTagKeys());
analysis.setTagValuesToGroupedTimeseriesOperands(tagValuesToGroupedTimeseriesOperands);
- analysis.setCrossGroupByExpressions(groupByTagOutputExpressions);
+ analysis.setCrossGroupByExpressions(outputExpressionToRawExpressionsMap);
}
private void analyzeDeviceToAggregation(
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 d0be42611a..cd8143ea08 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
@@ -1185,6 +1185,7 @@ public class ExpressionAnalyzer {
if (rawPath.isMeasurementAliasExists()) {
measurementWithSchema.setMeasurementAlias(rawPath.getMeasurementAlias());
}
+ measurementWithSchema.setTagMap(rawPath.getTagMap());
return new TimeSeriesOperand(measurementWithSchema);
} else if (expression instanceof LeafOperand) {
return expression;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java
index f8c84f38e5..a1e164c7d8 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.db.mpp.plan.analyze.ExpressionAnalyzer;
import org.apache.iotdb.db.mpp.plan.constant.StatementType;
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.mpp.plan.statement.Statement;
import org.apache.iotdb.db.mpp.plan.statement.StatementVisitor;
import org.apache.iotdb.db.mpp.plan.statement.component.FillComponent;
@@ -355,6 +356,9 @@ public class QueryStatement extends Statement {
: resultColumn.getExpression().getExpressionString());
}
if (isGroupByTag()) {
+ if (hasHaving()) {
+ throw new SemanticException("Having clause is not supported yet in GROUP BY TAGS query");
+ }
for (String s : getGroupByTagComponent().getTagKeys()) {
if (outputColumn.contains(s)) {
throw new SemanticException("Output column is duplicated with the tag key: " + s);
@@ -363,6 +367,15 @@ public class QueryStatement extends Statement {
if (rowLimit > 0 || rowOffset > 0 || seriesLimit > 0 || seriesOffset > 0) {
throw new SemanticException("Limit or slimit are not supported yet in GROUP BY TAGS");
}
+ for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
+ Expression expression = resultColumn.getExpression();
+ if (!(expression instanceof FunctionExpression
+ && expression.getExpressions().get(0) instanceof TimeSeriesOperand
+ && expression.isBuiltInAggregationFunctionExpression())) {
+ throw new SemanticException(
+ expression + " can't be used in group by tag. It will be supported in the future.");
+ }
+ }
}
} else {
if (isGroupByTime() || isGroupByLevel()) {
@@ -371,7 +384,7 @@ public class QueryStatement extends Statement {
}
}
- if (getHavingCondition() != null) {
+ if (hasHaving()) {
Expression havingExpression = getHavingCondition().getPredicate();
if (ExpressionAnalyzer.identifyOutputColumnType(havingExpression, true)
!= ResultColumn.ColumnType.AGGREGATION) {