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

caogaofei pushed a commit to branch beyyes/improve_query_fe
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/beyyes/improve_query_fe by 
this push:
     new 796e3df9783 add ut for QueryStatement and StatementGenerator
796e3df9783 is described below

commit 796e3df9783fafd2d01389a30758fbd0631cc487
Author: Beyyes <[email protected]>
AuthorDate: Mon Jun 26 20:03:22 2023 +0800

    add ut for QueryStatement and StatementGenerator
---
 .../plan/scheduler/load/LoadTsFileScheduler.java   |  11 +-
 .../db/mpp/plan/statement/crud/QueryStatement.java |  25 +---
 .../db/mpp/plan/parser/StatementGeneratorTest.java |  38 ++++--
 .../db/mpp/plan/statement/QueryStatementTest.java  | 147 +++++++++++++++++++++
 4 files changed, 183 insertions(+), 38 deletions(-)

diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/scheduler/load/LoadTsFileScheduler.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/scheduler/load/LoadTsFileScheduler.java
index f371e5e293e..6541ae4e5ef 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/scheduler/load/LoadTsFileScheduler.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/scheduler/load/LoadTsFileScheduler.java
@@ -327,12 +327,11 @@ public class LoadTsFileScheduler implements IScheduler {
       dispatcher.dispatchLocally(instance);
     } catch (FragmentInstanceDispatchException e) {
       logger.warn(
-          String.format(
-              "Dispatch tsFile %s error to local error. Result status code %s. 
"
-                  + "Result status message %s.",
-              node.getTsFileResource().getTsFile(),
-              TSStatusCode.representOf(e.getFailureStatus().getCode()).name(),
-              e.getFailureStatus().getMessage()));
+          "Dispatch tsFile {} error to local error. Result status code {}. "
+              + "Result status message {}.",
+          node.getTsFileResource().getTsFile(),
+          TSStatusCode.representOf(e.getFailureStatus().getCode()).name(),
+          e.getFailureStatus().getMessage());
       stateMachine.transitionToFailed(e.getFailureStatus());
       return false;
     }
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 2cf6154a1c4..d405696f0e2 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
@@ -333,10 +333,6 @@ public class QueryStatement extends Statement {
     return resultSetFormat == ResultSetFormat.ALIGN_BY_DEVICE;
   }
 
-  public boolean disableAlign() {
-    return resultSetFormat == ResultSetFormat.DISABLE_ALIGN;
-  }
-
   public boolean isOrderByTime() {
     return orderByComponent != null && orderByComponent.isOrderByTime();
   }
@@ -469,14 +465,11 @@ public class QueryStatement extends Statement {
     return useWildcard;
   }
 
-  private static final String RAW_AGGREGATION_HYBRID_QUERY_ERROR_MSG =
+  public static final String RAW_AGGREGATION_HYBRID_QUERY_ERROR_MSG =
       "Raw data and aggregation hybrid query is not supported.";
 
   public void semanticCheck() {
     if (isAggregationQuery()) {
-      if (disableAlign()) {
-        throw new SemanticException("AGGREGATION doesn't support disable align 
clause.");
-      }
       if (groupByComponent != null && isGroupByLevel()) {
         throw new SemanticException("GROUP BY CLAUSES doesn't support GROUP BY 
LEVEL now.");
       }
@@ -539,7 +532,7 @@ public class QueryStatement extends Statement {
       Expression whereExpression = getWhereCondition().getPredicate();
       if (ExpressionAnalyzer.identifyOutputColumnType(whereExpression, true)
           == ResultColumn.ColumnType.AGGREGATION) {
-        throw new SemanticException("aggregate functions are not supported in 
WHERE clause");
+        throw new SemanticException("Aggregate functions are not supported in 
WHERE clause");
       }
     }
 
@@ -600,9 +593,6 @@ public class QueryStatement extends Statement {
       if (isAlignByDevice()) {
         throw new SemanticException("Last query doesn't support align by 
device.");
       }
-      if (disableAlign()) {
-        throw new SemanticException("Disable align cannot be applied to LAST 
query.");
-      }
       for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
         Expression expression = resultColumn.getExpression();
         if (!(expression instanceof TimeSeriesOperand)) {
@@ -630,19 +620,16 @@ public class QueryStatement extends Statement {
 
     if (isSelectInto()) {
       if (getSeriesLimit() > 0) {
-        throw new SemanticException("select into: slimit clauses are not 
supported.");
+        throw new SemanticException("Select into: slimit clauses are not 
supported.");
       }
       if (getSeriesOffset() > 0) {
-        throw new SemanticException("select into: soffset clauses are not 
supported.");
-      }
-      if (disableAlign()) {
-        throw new SemanticException("select into: disable align clauses are 
not supported.");
+        throw new SemanticException("Select into: soffset clauses are not 
supported.");
       }
       if (isLastQuery()) {
-        throw new SemanticException("select into: last clauses are not 
supported.");
+        throw new SemanticException("Select into: last clauses are not 
supported.");
       }
       if (isGroupByTag()) {
-        throw new SemanticException("select into: GROUP BY TAGS clause are not 
supported.");
+        throw new SemanticException("Select into: GROUP BY TAGS clause are not 
supported.");
       }
     }
   }
diff --git 
a/server/src/test/java/org/apache/iotdb/db/mpp/plan/parser/StatementGeneratorTest.java
 
b/server/src/test/java/org/apache/iotdb/db/mpp/plan/parser/StatementGeneratorTest.java
index 1113033cfcd..f0747294d32 100644
--- 
a/server/src/test/java/org/apache/iotdb/db/mpp/plan/parser/StatementGeneratorTest.java
+++ 
b/server/src/test/java/org/apache/iotdb/db/mpp/plan/parser/StatementGeneratorTest.java
@@ -32,28 +32,35 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
+import static org.junit.Assert.assertEquals;
+
 public class StatementGeneratorTest {
 
   @Test
-  public void testRawDataQuery() {
-    List<String> selectExprList = Arrays.asList("s1", "s2");
-    List<String> prefixPaths = Collections.singletonList("root.sg1.d1");
+  public void rawDataQueryTest() {
+    String sql = "SELECT s1, s2 FROM root.sg1.d1 WHERE time > 1 and s3 > 2 
LIMIT 10 OFFSET 11";
     checkQueryStatement(
-        "SELECT s1, s2 FROM root.sg1.d1 LIMIT 10 OFFSET 10", selectExprList, 
prefixPaths, 10, 10);
+        sql,
+        Arrays.asList("s1", "s2"),
+        Collections.singletonList("root.sg1.d1"),
+        "Time > 1 & s3 > 2",
+        10,
+        11);
   }
 
   @Test
-  public void testGroupByTagWithDuplicatedKeys() {
+  public void groupByTagWithDuplicatedKeysTest() {
     try {
       checkQueryStatement(
           "SELECT avg(*) FROM root.sg.** GROUP BY TAGS(k1, k2, k1)",
           Collections.emptyList(),
           Collections.emptyList(),
+          "",
           10,
           10);
       Assert.fail();
     } catch (SemanticException e) {
-      Assert.assertEquals("duplicated key in GROUP BY TAGS: k1", 
e.getMessage());
+      assertEquals("duplicated key in GROUP BY TAGS: k1", e.getMessage());
     }
   }
 
@@ -62,7 +69,8 @@ public class StatementGeneratorTest {
   private void checkQueryStatement(
       String sql,
       List<String> selectExprList,
-      List<String> prefixPaths,
+      List<String> fromPrefixPaths,
+      String wherePredicateString,
       int rowLimit,
       int rowOffset) {
     QueryStatement statement =
@@ -72,20 +80,24 @@ public class StatementGeneratorTest {
     int cnt = 0;
     for (ResultColumn resultColumn : 
statement.getSelectComponent().getResultColumns()) {
       String selectExpr = resultColumn.getExpression().toString();
-      Assert.assertEquals(selectExprList.get(cnt++), selectExpr);
+      assertEquals(selectExprList.get(cnt++), selectExpr);
     }
-    Assert.assertEquals(selectExprList.size(), cnt);
+    assertEquals(selectExprList.size(), 
statement.getSelectComponent().getResultColumns().size());
 
     // check FROM clause
     cnt = 0;
     for (PartialPath path : statement.getFromComponent().getPrefixPaths()) {
-      Assert.assertEquals(prefixPaths.get(cnt++), path.toString());
+      assertEquals(fromPrefixPaths.get(cnt++), path.toString());
     }
-    Assert.assertEquals(prefixPaths.size(), cnt);
+    assertEquals(fromPrefixPaths.size(), 
statement.getFromComponent().getPrefixPaths().size());
+
+    // check WHERE clause
+    assertEquals(
+        wherePredicateString, 
statement.getWhereCondition().getPredicate().getExpressionString());
 
     // check LIMIT & OFFSET clause
-    Assert.assertEquals(rowLimit, statement.getRowLimit());
-    Assert.assertEquals(rowOffset, statement.getRowOffset());
+    assertEquals(rowLimit, statement.getRowLimit());
+    assertEquals(rowOffset, statement.getRowOffset());
 
     // TODO: add more clause
   }
diff --git 
a/server/src/test/java/org/apache/iotdb/db/mpp/plan/statement/QueryStatementTest.java
 
b/server/src/test/java/org/apache/iotdb/db/mpp/plan/statement/QueryStatementTest.java
new file mode 100644
index 00000000000..e90ac2ad25d
--- /dev/null
+++ 
b/server/src/test/java/org/apache/iotdb/db/mpp/plan/statement/QueryStatementTest.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.mpp.plan.statement;
+
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.parser.StatementGenerator;
+import org.apache.iotdb.db.mpp.plan.statement.crud.QueryStatement;
+import org.apache.iotdb.tsfile.utils.Pair;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.time.ZonedDateTime;
+import java.util.Arrays;
+import java.util.List;
+
+import static 
org.apache.iotdb.db.mpp.plan.statement.crud.QueryStatement.RAW_AGGREGATION_HYBRID_QUERY_ERROR_MSG;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class QueryStatementTest {
+
+  private static final Logger logger = 
LoggerFactory.getLogger(QueryStatementTest.class);
+
+  private static final String ALIGN_BY_DEVICE_ONE_LEVEL_ERROR =
+      "ALIGN BY DEVICE: the suffix paths can only be measurement or one-level 
wildcard";
+
+  @Test
+  public void semanticCheckTest() {
+    List<Pair<String, String>> errorSqlWithMessages =
+        Arrays.asList(
+            new Pair<>(
+                "SELECT s1 FROM root.sg.d1 GROUP BY ([2017-11-01T00:00:00, 
2017-11-07T23:00:00),1d)",
+                "Common queries and aggregated queries are not allowed to 
appear at the same time"),
+            new Pair<>(
+                "SELECT count(s1),s2 FROM root.sg.d1", 
RAW_AGGREGATION_HYBRID_QUERY_ERROR_MSG),
+
+            // test for where clause
+            new Pair<>(
+                "SELECT s1 FROM root.sg.d1 WHERE count(s1) > 0",
+                "Aggregate functions are not supported in WHERE clause"),
+
+            // test for having clause
+            new Pair<>(
+                "SELECT s1 FROM root.sg.d1 HAVING(s1 > 0)",
+                "Expression of HAVING clause must to be an Aggregation"),
+            new Pair<>(
+                "SELECT s1 FROM root.sg.d1 HAVING(count(s1) > 0)",
+                "Expression of HAVING clause can not be used in 
NonAggregationQuery"),
+            new Pair<>(
+                "SELECT count(d1.s1) FROM root.sg.d1 GROUP BY level=1 HAVING 
(count(s1) > 0)",
+                "When Having used with GroupByLevel: the suffix paths can only 
be measurement or one-level wildcard"),
+            new Pair<>(
+                "SELECT count(s1) FROM root.sg.d1 GROUP BY level=1 HAVING 
(count(sg.d1.s1) > 0)",
+                "When Having used with GroupByLevel: the suffix paths can only 
be measurement or one-level wildcard"),
+
+            // test for align by device clause
+            new Pair<>(
+                "SELECT d1.s1 FROM root.sg.d1 align by device", 
ALIGN_BY_DEVICE_ONE_LEVEL_ERROR),
+            new Pair<>(
+                "SELECT count(s1) FROM root.sg.d1 group by variation(sg.s1) 
align by device",
+                ALIGN_BY_DEVICE_ONE_LEVEL_ERROR),
+            new Pair<>(
+                "SELECT s1 FROM root.sg.d1 order by root.sg.d1.s1 align by 
device",
+                ALIGN_BY_DEVICE_ONE_LEVEL_ERROR),
+            new Pair<>(
+                "SELECT s1 FROM root.sg.d1 where root.sg.d1.s1 > 0 align by 
device",
+                ALIGN_BY_DEVICE_ONE_LEVEL_ERROR),
+            new Pair<>(
+                "SELECT count(s1) FROM root.sg.d1 having(count(root.sg.d1.s1) 
> 0) align by device",
+                ALIGN_BY_DEVICE_ONE_LEVEL_ERROR),
+            new Pair<>(
+                "SELECT s1 FROM root.sg.d1 order by timeseries align by 
device",
+                "Sorting by timeseries is only supported in last queries."),
+
+            // test for last query
+            new Pair<>(
+                "SELECT last s1 FROM root.sg.d1 align by device",
+                "Last query doesn't support align by device."),
+            new Pair<>(
+                "SELECT last s1+s2 FROM root.sg.d1",
+                "Last queries can only be applied on raw time series."),
+            new Pair<>(
+                "SELECT last s1 FROM root.sg.d1 order by device",
+                "Sorting by device is only supported in ALIGN BY DEVICE 
queries."),
+            new Pair<>(
+                "SELECT last s1 FROM root.sg.d1 SLIMIT 1 SOFFSET 2",
+                "SLIMIT and SOFFSET can not be used in LastQuery."),
+
+            // test for select into clause
+            new Pair<>(
+                "SELECT s1 INTO root.sg.d2(t1) FROM root.sg.d1 SLIMIT 5",
+                "Select into: slimit clauses are not supported."),
+            new Pair<>(
+                "SELECT s1 INTO root.sg.d2(t1) FROM root.sg.d1 SOFFSET 6",
+                "Select into: soffset clauses are not supported."),
+            new Pair<>(
+                "SELECT last s1 INTO root.sg.d2(t1) FROM root.sg.d1",
+                "Select into: last clauses are not supported."),
+            new Pair<>(
+                "SELECT count(s1) INTO root.sg.d2(t1) FROM root.sg.d1 GROUP BY 
TAGS(a)",
+                "Select into: GROUP BY TAGS clause are not supported."),
+            new Pair<>(
+                "SELECT s1 FROM root.sg.d1 order by timeseries",
+                "Sorting by timeseries is only supported in last queries."),
+            new Pair<>(
+                "SELECT s1 FROM root.sg.d1 order by device",
+                "Sorting by device is only supported in ALIGN BY DEVICE 
queries."));
+
+    for (Pair<String, String> pair : errorSqlWithMessages) {
+      String errorSql = pair.left;
+      String errorMsg = pair.right;
+      try {
+        checkErrorQuerySql(errorSql);
+      } catch (SemanticException e) {
+        assertEquals(errorMsg, e.getMessage());
+      } catch (Exception ex) {
+        logger.error("Meets error in test sql: {}", errorSql, ex);
+        fail();
+      }
+    }
+  }
+
+  private void checkErrorQuerySql(String sql) {
+    QueryStatement statement =
+        (QueryStatement) StatementGenerator.createStatement(sql, 
ZonedDateTime.now().getOffset());
+    statement.semanticCheck();
+  }
+}

Reply via email to