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) {