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

xiangweiwei 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 9b06cae  [IOTDB-1303] Group by without aggregation function used in 
select clause (#3011)
9b06cae is described below

commit 9b06cae589b0cfa0f0a37ababb6c17b16b586bb6
Author: Xiangwei Wei <[email protected]>
AuthorDate: Tue Apr 20 16:41:29 2021 +0800

    [IOTDB-1303] Group by without aggregation function used in select clause 
(#3011)
---
 .../iotdb/db/qp/physical/crud/GroupByTimePlan.java |  2 +
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    | 10 +++
 .../iotdb/db/qp/strategy/PhysicalGenerator.java    | 49 +++++------
 .../iotdb/db/integration/IOTDBGroupByIT.java       | 19 +++++
 .../iotdb/db/integration/IoTDBGroupByFillIT.java   | 97 +++++++++++-----------
 .../aggregation/IoTDBAggregationByLevelIT.java     | 21 +++++
 6 files changed, 121 insertions(+), 77 deletions(-)

diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/GroupByTimePlan.java
 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/GroupByTimePlan.java
index 6c906bf..c530daf 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/GroupByTimePlan.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/GroupByTimePlan.java
@@ -22,6 +22,8 @@ import org.apache.iotdb.db.qp.logical.Operator;
 
 public class GroupByTimePlan extends AggregationPlan {
 
+  public static final String LACK_FUNC_ERROR_MESSAGE =
+      "Lack aggregation function in group by query";
   // [startTime, endTime)
   private long startTime;
   private long endTime;
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java 
b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
index 8326c02..b5906a8 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
@@ -77,6 +77,7 @@ import 
org.apache.iotdb.db.qp.logical.sys.ShowTriggersOperator;
 import org.apache.iotdb.db.qp.logical.sys.StartTriggerOperator;
 import org.apache.iotdb.db.qp.logical.sys.StopTriggerOperator;
 import org.apache.iotdb.db.qp.logical.sys.TracingOperator;
+import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser.AggregationCallContext;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser.AggregationElementContext;
 import org.apache.iotdb.db.qp.sql.SqlBaseParser.AliasClauseContext;
@@ -1332,6 +1333,9 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   }
 
   public void parseGroupByLevelClause(GroupByLevelClauseContext ctx, 
QueryOperator queryOp) {
+    if (!queryOp.hasAggregation()) {
+      throw new SQLParserException(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE);
+    }
     queryOp.setGroupByLevel(true);
     queryOp.setLevel(Integer.parseInt(ctx.INT().getText()));
   }
@@ -1423,6 +1427,9 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   }
 
   private void parseGroupByTimeClause(GroupByTimeClauseContext ctx, 
QueryOperator queryOp) {
+    if (!queryOp.hasAggregation()) {
+      throw new SQLParserException(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE);
+    }
     queryOp.setGroupByTime(true);
     queryOp.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null);
     // parse timeUnit
@@ -1448,6 +1455,9 @@ public class IoTDBSqlVisitor extends 
SqlBaseBaseVisitor<Operator> {
   }
 
   private void parseGroupByFillClause(GroupByFillClauseContext ctx, 
QueryOperator queryOp) {
+    if (!queryOp.hasAggregation()) {
+      throw new SQLParserException(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE);
+    }
     queryOp.setGroupByTime(true);
     queryOp.setFill(true);
     queryOp.setLeftCRightO(ctx.timeInterval().LS_BRACKET() != null);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
index 52c3fc1..66181d7 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
@@ -254,8 +254,7 @@ public class PhysicalGenerator {
         TracingOperator tracingOperator = (TracingOperator) operator;
         return new TracingPlan(tracingOperator.isTracingOn());
       case QUERY:
-        QueryOperator query = (QueryOperator) operator;
-        return transformQuery(query, fetchSize);
+        return transformQuery((QueryOperator) operator);
       case TTL:
         switch (operator.getTokenIntType()) {
           case SQLConstant.TOK_SET:
@@ -434,15 +433,14 @@ public class PhysicalGenerator {
   }
 
   interface Transfrom {
-    QueryPlan transform(QueryOperator queryOperator, int fetchSize) throws 
QueryProcessException;
+    QueryPlan transform(QueryOperator queryOperator) throws 
QueryProcessException;
   }
 
   /** agg physical plan transform */
   public static class AggPhysicalPlanRule implements Transfrom {
 
     @Override
-    public QueryPlan transform(QueryOperator queryOperator, int fetchSize)
-        throws QueryProcessException {
+    public QueryPlan transform(QueryOperator queryOperator) throws 
QueryProcessException {
       QueryPlan queryPlan;
       if (queryOperator.hasUdf()) {
         throw new QueryProcessException(
@@ -459,17 +457,18 @@ public class PhysicalGenerator {
           
.setAggregations(queryOperator.getSelectOperator().getAggregations());
 
       if (queryOperator.isGroupByTime()) {
-        ((GroupByTimePlan) queryPlan).setInterval(queryOperator.getUnit());
-        ((GroupByTimePlan) 
queryPlan).setIntervalByMonth(queryOperator.isIntervalByMonth());
-        ((GroupByTimePlan) 
queryPlan).setSlidingStep(queryOperator.getSlidingStep());
-        ((GroupByTimePlan) 
queryPlan).setSlidingStepByMonth(queryOperator.isSlidingStepByMonth());
-        ((GroupByTimePlan) 
queryPlan).setLeftCRightO(queryOperator.isLeftCRightO());
+        GroupByTimePlan groupByTimePlan = (GroupByTimePlan) queryPlan;
+        groupByTimePlan.setInterval(queryOperator.getUnit());
+        groupByTimePlan.setIntervalByMonth(queryOperator.isIntervalByMonth());
+        groupByTimePlan.setSlidingStep(queryOperator.getSlidingStep());
+        
groupByTimePlan.setSlidingStepByMonth(queryOperator.isSlidingStepByMonth());
+        groupByTimePlan.setLeftCRightO(queryOperator.isLeftCRightO());
         if (!queryOperator.isLeftCRightO()) {
-          ((GroupByTimePlan) 
queryPlan).setStartTime(queryOperator.getStartTime() + 1);
-          ((GroupByTimePlan) queryPlan).setEndTime(queryOperator.getEndTime() 
+ 1);
+          groupByTimePlan.setStartTime(queryOperator.getStartTime() + 1);
+          groupByTimePlan.setEndTime(queryOperator.getEndTime() + 1);
         } else {
-          ((GroupByTimePlan) 
queryPlan).setStartTime(queryOperator.getStartTime());
-          ((GroupByTimePlan) queryPlan).setEndTime(queryOperator.getEndTime());
+          groupByTimePlan.setStartTime(queryOperator.getStartTime());
+          groupByTimePlan.setEndTime(queryOperator.getEndTime());
         }
       }
       if (queryOperator.isFill()) {
@@ -497,33 +496,30 @@ public class PhysicalGenerator {
   public static class FillPhysicalPlanRule implements Transfrom {
 
     @Override
-    public QueryPlan transform(QueryOperator queryOperator, int fetchSize)
-        throws QueryProcessException {
-      QueryPlan queryPlan;
+    public QueryPlan transform(QueryOperator queryOperator) throws 
QueryProcessException {
       if (queryOperator.hasUdf()) {
         throw new QueryProcessException("Fill functions are not supported in 
UDF queries.");
       }
-      queryPlan = new FillQueryPlan();
+      FillQueryPlan queryPlan = new FillQueryPlan();
       FilterOperator timeFilter = queryOperator.getFilterOperator();
       if (!timeFilter.isSingle()) {
         throw new QueryProcessException("Slice query must select a single time 
point");
       }
       long time = Long.parseLong(((BasicFunctionOperator) 
timeFilter).getValue());
-      ((FillQueryPlan) queryPlan).setQueryTime(time);
-      ((FillQueryPlan) queryPlan).setFillType(queryOperator.getFillTypes());
+      queryPlan.setQueryTime(time);
+      queryPlan.setFillType(queryOperator.getFillTypes());
       return queryPlan;
     }
   }
 
   @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity 
warning
-  private PhysicalPlan transformQuery(QueryOperator queryOperator, int 
fetchSize)
-      throws QueryProcessException {
+  private PhysicalPlan transformQuery(QueryOperator queryOperator) throws 
QueryProcessException {
     QueryPlan queryPlan = null;
 
     if (queryOperator.hasAggregation()) {
-      queryPlan = new AggPhysicalPlanRule().transform(queryOperator, 
fetchSize);
+      queryPlan = new AggPhysicalPlanRule().transform(queryOperator);
     } else if (queryOperator.isFill()) {
-      queryPlan = new FillPhysicalPlanRule().transform(queryOperator, 
fetchSize);
+      queryPlan = new FillPhysicalPlanRule().transform(queryOperator);
     } else if (queryOperator.isLastQuery()) {
       queryPlan = new LastQueryPlan();
     } else if (queryOperator.getIndexType() != null) {
@@ -536,7 +532,7 @@ public class PhysicalGenerator {
     }
 
     if (queryOperator.isAlignByDevice()) {
-      queryPlan = getAlignQueryPlan(queryOperator, fetchSize, queryPlan);
+      queryPlan = getAlignQueryPlan(queryOperator, queryPlan);
     } else {
       queryPlan.setPaths(queryOperator.getSelectedPaths());
       // Last query result set will not be affected by alignment
@@ -586,8 +582,7 @@ public class PhysicalGenerator {
   }
 
   @SuppressWarnings("squid:S3777") // Suppress high Cognitive Complexity 
warning
-  private QueryPlan getAlignQueryPlan(
-      QueryOperator queryOperator, int fetchSize, QueryPlan queryPlan)
+  private QueryPlan getAlignQueryPlan(QueryOperator queryOperator, QueryPlan 
queryPlan)
       throws QueryProcessException {
     // below is the core realization of ALIGN_BY_DEVICE sql logic
     AlignByDevicePlan alignByDevicePlan = new AlignByDevicePlan();
diff --git 
a/server/src/test/java/org/apache/iotdb/db/integration/IOTDBGroupByIT.java 
b/server/src/test/java/org/apache/iotdb/db/integration/IOTDBGroupByIT.java
index 3d16ddf..624977f 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IOTDBGroupByIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IOTDBGroupByIT.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.integration;
 
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.compaction.CompactionStrategy;
+import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.jdbc.Config;
 
@@ -931,6 +932,24 @@ public class IOTDBGroupByIT {
     }
   }
 
+  /**
+   * Test group by without aggregation function used in select clause. The 
expected situation is
+   * throwing an exception.
+   */
+  @Test
+  public void TestGroupByWithoutAggregationFunc() {
+    try (Connection connection =
+            DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", 
"root", "root");
+        Statement statement = connection.createStatement()) {
+
+      statement.execute("select temperature from root.ln.wf01.wt01 group by 
([0, 100), 5ms)");
+
+      fail("No expected exception thrown");
+    } catch (Exception e) {
+      
Assert.assertTrue(e.getMessage().contains(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE));
+    }
+  }
+
   private void prepareData() {
     try (Connection connection =
             DriverManager.getConnection(
diff --git 
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java 
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
index 0257e0b..a1c06bb 100644
--- 
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
+++ 
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBGroupByFillIT.java
@@ -19,11 +19,13 @@
 package org.apache.iotdb.db.integration;
 
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.jdbc.Config;
 import org.apache.iotdb.jdbc.IoTDBSQLException;
 
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -90,8 +92,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([17, 48), 5ms) FILL(int32[previous])");
 
       assertTrue(hasResultSet);
@@ -111,8 +112,7 @@ public class IoTDBGroupByFillIT {
 
       hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([17, 48), 5ms) FILL(int32[previous]) order by 
time desc");
 
       assertTrue(hasResultSet);
@@ -141,8 +141,7 @@ public class IoTDBGroupByFillIT {
             DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", 
"root", "root");
         Statement statement = connection.createStatement()) {
       statement.execute(
-          "select count(temperature) from "
-              + "root.ln.wf01.wt01 "
+          "select count(temperature) from root.ln.wf01.wt01 "
               + "GROUP BY ([17, 48), 5ms) FILL(int32[previous])");
     } catch (IoTDBSQLException e) {
       assertTrue(e.getMessage().contains("Group By Fill only support 
last_value function"));
@@ -155,8 +154,7 @@ public class IoTDBGroupByFillIT {
             DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", 
"root", "root");
         Statement statement = connection.createStatement()) {
       statement.execute(
-          "select count(temperature) from "
-              + "root.ln.wf01.wt01 "
+          "select count(temperature) from root.ln.wf01.wt01 "
               + "GROUP BY ([17, 48), 5ms) FILL(int32[previous]) order by time 
desc");
     } catch (IoTDBSQLException e) {
       assertTrue(e.getMessage().contains("Group By Fill only support 
last_value function"));
@@ -178,8 +176,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) FILL(int32[previous])");
 
       assertTrue(hasResultSet);
@@ -199,8 +196,7 @@ public class IoTDBGroupByFillIT {
 
       hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) FILL(int32[previous]) order by 
time desc");
 
       assertTrue(hasResultSet);
@@ -244,8 +240,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature), last_value(hardware) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature), last_value(hardware) from 
root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) FILL(int32[previous], 
double[previous])");
 
       assertTrue(hasResultSet);
@@ -267,8 +262,7 @@ public class IoTDBGroupByFillIT {
 
       hasResultSet =
           statement.execute(
-              "select last_value(temperature), last_value(hardware) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature), last_value(hardware) from 
root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) FILL(int32[previous], 
double[previous]) order by time desc");
 
       assertTrue(hasResultSet);
@@ -305,8 +299,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ((5, 40], 5ms) FILL(int32[previous])");
 
       assertTrue(hasResultSet);
@@ -326,8 +319,7 @@ public class IoTDBGroupByFillIT {
 
       hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ((5, 40], 5ms) FILL(int32[previous]) order by 
time desc");
 
       assertTrue(hasResultSet);
@@ -370,8 +362,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature), last_value(hardware) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature), last_value(hardware) from 
root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) FILL(ALL[previous])");
 
       assertTrue(hasResultSet);
@@ -393,8 +384,7 @@ public class IoTDBGroupByFillIT {
 
       hasResultSet =
           statement.execute(
-              "select last_value(temperature), last_value(hardware) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature), last_value(hardware) from 
root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) FILL(ALL[previous]) order by time 
desc");
 
       assertTrue(hasResultSet);
@@ -430,8 +420,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([17, 48), 5ms) FILL(int32[previousUntilLast])");
 
       assertTrue(hasResultSet);
@@ -450,8 +439,7 @@ public class IoTDBGroupByFillIT {
       }
       hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([17, 48), 5ms) FILL(int32[previousUntilLast]) 
order by time desc");
 
       assertTrue(hasResultSet);
@@ -479,8 +467,7 @@ public class IoTDBGroupByFillIT {
             DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", 
"root", "root");
         Statement statement = connection.createStatement()) {
       statement.execute(
-          "select count(temperature) from "
-              + "root.ln.wf01.wt01 "
+          "select count(temperature) from root.ln.wf01.wt01 "
               + "GROUP BY ([17, 48), 5ms) FILL(int32[previousUntilLast])");
     } catch (IoTDBSQLException e) {
       System.out.println(e.getMessage());
@@ -494,8 +481,7 @@ public class IoTDBGroupByFillIT {
             DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", 
"root", "root");
         Statement statement = connection.createStatement()) {
       statement.execute(
-          "select count(temperature) from "
-              + "root.ln.wf01.wt01 "
+          "select count(temperature) from root.ln.wf01.wt01 "
               + "GROUP BY ([17, 48), 5ms) FILL(int32[previousUntilLast]) order 
by time desc");
     } catch (IoTDBSQLException e) {
       System.out.println(e.getMessage());
@@ -519,8 +505,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) FILL(int32[previousUntilLast])");
 
       assertTrue(hasResultSet);
@@ -540,8 +525,7 @@ public class IoTDBGroupByFillIT {
 
       hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) 
FILL(int32[previousUntilLast])order by time desc");
 
       assertTrue(hasResultSet);
@@ -584,8 +568,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature), last_value(hardware) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature), last_value(hardware) from 
root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) FILL(int32[previousUntilLast], 
double[previousUntilLast])");
 
       assertTrue(hasResultSet);
@@ -607,8 +590,7 @@ public class IoTDBGroupByFillIT {
 
       hasResultSet =
           statement.execute(
-              "select last_value(temperature), last_value(hardware) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature), last_value(hardware) from 
root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) FILL(int32[previousUntilLast], 
double[previousUntilLast]) order by time desc");
 
       assertTrue(hasResultSet);
@@ -644,8 +626,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([17, 48), 5ms) FILL(float[previousUntilLast])");
 
       assertTrue(hasResultSet);
@@ -665,8 +646,7 @@ public class IoTDBGroupByFillIT {
 
       hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([17, 48), 5ms) FILL(float[previousUntilLast]) 
order by time desc");
 
       assertTrue(hasResultSet);
@@ -699,8 +679,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ((4, 44], 5ms) FILL(int32[previousUntilLast])");
 
       assertTrue(hasResultSet);
@@ -745,8 +724,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature), last_value(hardware) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature), last_value(hardware) from 
root.ln.wf01.wt01 "
                   + "GROUP BY ([2, 48), 5ms) FILL(ALL[previousUntilLast])");
 
       assertTrue(hasResultSet);
@@ -785,8 +763,7 @@ public class IoTDBGroupByFillIT {
         Statement statement = connection.createStatement()) {
       boolean hasResultSet =
           statement.execute(
-              "select last_value(temperature) from "
-                  + "root.ln.wf01.wt01 "
+              "select last_value(temperature) from root.ln.wf01.wt01 "
                   + "GROUP BY ([17, 48), 5ms) FILL(int32[previous]) "
                   + "limit 5 offset 2");
 
@@ -811,6 +788,26 @@ public class IoTDBGroupByFillIT {
     }
   }
 
+  /**
+   * Test group by fill without aggregation function used in select clause. 
The expected situation
+   * is throwing an exception.
+   */
+  @Test
+  public void TestGroupByFillWithoutAggregationFunc() {
+    try (Connection connection =
+            DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", 
"root", "root");
+        Statement statement = connection.createStatement()) {
+
+      statement.execute(
+          "select temperature from root.ln.wf01.wt01 "
+              + "group by ([0, 100), 5ms) FILL(int32[previous])");
+
+      fail("No expected exception thrown");
+    } catch (Exception e) {
+      
Assert.assertTrue(e.getMessage().contains(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE));
+    }
+  }
+
   private void prepareData() {
     try (Connection connection =
             DriverManager.getConnection(
diff --git 
a/server/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBAggregationByLevelIT.java
 
b/server/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBAggregationByLevelIT.java
index c1a7e14..0da4e16 100644
--- 
a/server/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBAggregationByLevelIT.java
+++ 
b/server/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBAggregationByLevelIT.java
@@ -20,6 +20,7 @@ package org.apache.iotdb.db.integration.aggregation;
 
 import org.apache.iotdb.db.constant.TestConstant;
 import org.apache.iotdb.db.qp.Planner;
+import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.jdbc.Config;
 
@@ -33,6 +34,8 @@ import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.Statement;
 
+import static org.junit.Assert.fail;
+
 public class IoTDBAggregationByLevelIT {
 
   private Planner planner = new Planner();
@@ -322,6 +325,24 @@ public class IoTDBAggregationByLevelIT {
     }
   }
 
+  /**
+   * Test group by level without aggregation function used in select clause. 
The expected situation
+   * is throwing an exception.
+   */
+  @Test
+  public void TestGroupByLevelWithoutAggregationFunc() {
+    try (Connection connection =
+            DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", 
"root", "root");
+        Statement statement = connection.createStatement()) {
+
+      statement.execute("select temperature from root.sg1.* group by level = 
2");
+
+      fail("No expected exception thrown");
+    } catch (Exception e) {
+      
Assert.assertTrue(e.getMessage().contains(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE));
+    }
+  }
+
   private void prepareData() {
     try (Connection connection =
             DriverManager.getConnection(

Reply via email to