This is an automated email from the ASF dual-hosted git repository.

hui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new a751beccc1 [IOTDB-3922] Fix incorrect column name in some scenarios 
for GroupByLevel (#6789)
a751beccc1 is described below

commit a751beccc1f889de8a1d6ffd9cc4917455b05160
Author: liuminghui233 <[email protected]>
AuthorDate: Thu Jul 28 09:40:50 2022 +0800

    [IOTDB-3922] Fix incorrect column name in some scenarios for GroupByLevel 
(#6789)
---
 .../org/apache/iotdb/db/it/query/IoTDBAliasIT.java | 27 ++++++
 .../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java  | 97 +++++++++++++++-------
 .../db/mpp/plan/analyze/ExpressionAnalyzer.java    |  8 +-
 .../mpp/plan/analyze/GroupByLevelController.java   | 16 +++-
 .../iotdb/db/qp/utils/GroupByLevelController.java  | 35 +++++---
 5 files changed, 133 insertions(+), 50 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAliasIT.java 
b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAliasIT.java
index 8ef5fc7181..21bc7371bd 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAliasIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAliasIT.java
@@ -381,4 +381,31 @@ public class IoTDBAliasIT {
       resultSetEqualTest(sqls.get(i), expectHeaders.get(i), retArrays.get(i));
     }
   }
+
+  // ------------------------------------ Function name 
--------------------------------------
+
+  @Test
+  public void aggregationFuncNameTest() {
+    String expectedHeader =
+        "count(root.sg.d1.temperature),count(root.sg.d2.temperature),"
+            + "COUNT(root.sg.d1.s2),COUNT(root.sg.d2.s2),"
+            + "CoUnT(root.sg.d1.temperature),CoUnT(root.sg.d2.temperature),";
+    String[] retArray = new String[] {"4,4,4,4,4,4,"};
+
+    resultSetEqualTest(
+        "select count(temperature),COUNT(s2),CoUnT(temperature) from 
root.sg.*",
+        expectedHeader,
+        retArray);
+  }
+
+  @Test
+  public void groupByLevelFuncNameTest() {
+    String expectedHeader = 
"count(root.sg.*.s2),COUNT(root.sg.*.temperature),CoUnT(root.sg.*.s2),";
+    String[] retArray = new String[] {"8,8,8,"};
+
+    resultSetEqualTest(
+        "select count(s2),COUNT(temperature),CoUnT(s2) from root.sg.* group by 
level = 1",
+        expectedHeader,
+        retArray);
+  }
 }
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 69980a72f1..3541df27ef 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
@@ -424,11 +424,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();
@@ -445,22 +446,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;
@@ -681,6 +688,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);
@@ -690,34 +698,59 @@ 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> rawExpressions = 
rawGroupByLevelExpressions.get(groupedExpression);
+        rawExpressions.forEach(
+            expression -> ExpressionAnalyzer.updateTypeProvider(expression, 
typeProvider));
+        rawExpressions.forEach(expression -> 
expression.inferTypes(typeProvider));
+
+        Set<Expression> rawExpressionsWithoutAlias =
+            rawExpressions.stream()
+                .map(ExpressionAnalyzer::removeAliasFromExpression)
+                .collect(Collectors.toSet());
+        rawExpressionsWithoutAlias.forEach(
+            expression -> ExpressionAnalyzer.updateTypeProvider(expression, 
typeProvider));
+        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 584849ab36..b3ddc5d2c2 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
@@ -983,10 +983,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;
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 a583805e33..4f8da81f15 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
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
 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;
@@ -81,7 +82,7 @@ public class GroupByLevelController {
     }
 
     PartialPath rawPath = ((TimeSeriesOperand) 
expression.getExpressions().get(0)).getPath();
-    PartialPath groupedPath = generatePartialPathByLevel(isCountStar, 
rawPath.getNodes(), levels);
+    PartialPath groupedPath = generatePartialPathByLevel(isCountStar, rawPath, 
levels);
 
     checkDatatypeConsistency(
         groupedPath.getFullPath(), ((FunctionExpression) 
expression).getFunctionName(), rawPath);
@@ -179,7 +180,8 @@ public class GroupByLevelController {
    * @return result partial path
    */
   public PartialPath generatePartialPathByLevel(
-      boolean isCountStar, String[] nodes, int[] pathLevels) {
+      boolean isCountStar, PartialPath rawPath, int[] pathLevels) {
+    String[] nodes = rawPath.getNodes();
     Set<Integer> levelSet = new HashSet<>();
     for (int level : pathLevels) {
       levelSet.add(level);
@@ -200,7 +202,15 @@ public class GroupByLevelController {
     } else {
       transformedNodes.add(nodes[nodes.length - 1]);
     }
-    return new PartialPath(transformedNodes.toArray(new String[0]));
+
+    MeasurementPath groupedPath =
+        new MeasurementPath(
+            new PartialPath(transformedNodes.toArray(new String[0])),
+            ((MeasurementPath) rawPath).getMeasurementSchema());
+    if (rawPath.isMeasurementAliasExists()) {
+      groupedPath.setMeasurementAlias(rawPath.getMeasurementAlias());
+    }
+    return groupedPath;
   }
 
   public Map<Expression, Set<Expression>> getGroupedPathMap() {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/utils/GroupByLevelController.java 
b/server/src/main/java/org/apache/iotdb/db/qp/utils/GroupByLevelController.java
index 781838c88b..0261b0a3b6 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/utils/GroupByLevelController.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/utils/GroupByLevelController.java
@@ -22,14 +22,15 @@ package org.apache.iotdb.db.qp.utils;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
+import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.ResultColumn;
 import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
 import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
-import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -113,8 +114,7 @@ public class GroupByLevelController {
           List<PartialPath> paths = ((FunctionExpression) 
expression).getPaths();
           String functionName = ((FunctionExpression) 
expression).getFunctionName();
           boolean isCountStar = countWildcardIterIndices.contains(idx++);
-          String groupedPath =
-              generatePartialPathByLevel(isCountStar, paths.get(0).getNodes(), 
levels);
+          String groupedPath = generatePartialPathByLevel(isCountStar, 
paths.get(0), levels);
           String rawPath = String.format("%s(%s)", functionName, 
paths.get(0).getFullPath());
           String pathWithFunction = String.format("%s(%s)", functionName, 
groupedPath);
 
@@ -207,28 +207,39 @@ public class GroupByLevelController {
    *
    * @return result partial path
    */
-  public String generatePartialPathByLevel(boolean isCountStar, String[] 
nodes, int[] pathLevels) {
+  public String generatePartialPathByLevel(
+      boolean isCountStar, PartialPath rawPath, int[] pathLevels) {
+    String[] nodes = rawPath.getNodes();
     Set<Integer> levelSet = new HashSet<>();
     for (int level : pathLevels) {
       levelSet.add(level);
     }
 
-    StringBuilder transformedPath = new StringBuilder();
-    transformedPath.append(nodes[0]).append(TsFileConstant.PATH_SEPARATOR);
+    List<String> transformedNodes = new ArrayList<>(nodes.length);
+
+    transformedNodes.add(nodes[0]);
     for (int k = 1; k < nodes.length - 1; k++) {
       if (levelSet.contains(k)) {
-        transformedPath.append(nodes[k]);
+        transformedNodes.add(nodes[k]);
       } else {
-        transformedPath.append(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD);
+        transformedNodes.add(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD);
       }
-      transformedPath.append(TsFileConstant.PATH_SEPARATOR);
     }
     if (isCountStar) {
-      transformedPath.append(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD);
+      transformedNodes.add(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD);
     } else {
-      transformedPath.append(nodes[nodes.length - 1]);
+      transformedNodes.add(nodes[nodes.length - 1]);
+    }
+
+    MeasurementPath groupedPath =
+        new MeasurementPath(
+            new PartialPath(transformedNodes.toArray(new String[0])),
+            ((MeasurementPath) rawPath).getMeasurementSchema());
+    if (rawPath.isMeasurementAliasExists()) {
+      groupedPath.setMeasurementAlias(rawPath.getMeasurementAlias());
+      return groupedPath.getFullPathWithAlias();
     }
-    return transformedPath.toString();
+    return groupedPath.getFullPath();
   }
 
   public void serialize(ByteBuffer byteBuffer) {

Reply via email to