You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ro...@apache.org on 2021/12/13 04:46:57 UTC
[iotdb] branch master updated: [IOTDB-1973] Supports aggregate queries, constants, and arithmetic nested expressions in SELECT clauses (#4453)
This is an automated email from the ASF dual-hosted git repository.
rong 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 9d2df64 [IOTDB-1973] Supports aggregate queries, constants, and arithmetic nested expressions in SELECT clauses (#4453)
9d2df64 is described below
commit 9d2df64422238222ac7b65ab1040894d910148ce
Author: LLY <48...@users.noreply.github.com>
AuthorDate: Mon Dec 13 12:46:04 2021 +0800
[IOTDB-1973] Supports aggregate queries, constants, and arithmetic nested expressions in SELECT clauses (#4453)
Co-authored-by: Steve Yurong Su <ro...@apache.org>
---
.../DML-Data-Manipulation-Language.md | 27 +-
.../DML-Data-Manipulation-Language.md | 29 +-
.../IoTDBUserDefinedAggregationFunctionIT.java | 725 +++++++++++++++++++++
.../iotdb/db/qp/logical/crud/QueryOperator.java | 2 +-
.../iotdb/db/qp/logical/crud/SelectComponent.java | 21 +-
.../db/qp/logical/crud/UDAFQueryOperator.java | 45 +-
...DFQueryOperator.java => UDTFQueryOperator.java} | 6 +-
.../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java | 11 +-
.../iotdb/db/qp/utils/GroupByLevelController.java | 4 +-
.../iotdb/db/query/expression/Expression.java | 4 +-
.../query/expression/binary/BinaryExpression.java | 12 +-
.../query/expression/unary/FunctionExpression.java | 38 +-
.../query/expression/unary/NegationExpression.java | 7 +-
13 files changed, 858 insertions(+), 73 deletions(-)
diff --git a/docs/UserGuide/IoTDB-SQL-Language/DML-Data-Manipulation-Language.md b/docs/UserGuide/IoTDB-SQL-Language/DML-Data-Manipulation-Language.md
index 062e4cd..8597e7e 100644
--- a/docs/UserGuide/IoTDB-SQL-Language/DML-Data-Manipulation-Language.md
+++ b/docs/UserGuide/IoTDB-SQL-Language/DML-Data-Manipulation-Language.md
@@ -1115,6 +1115,28 @@ Total line number = 1
It costs 0.009s
```
+Input:
+
+```sql
+select count(a),
+ count(b),
+ ((count(a) + 1) * 2 - 1) % 2 + 1.5,
+ -(count(a) + count(b)) * (count(a) * count(b)) + count(a) / count(b)
+from root.sg;
+```
+
+Result:
+
+```
++----------------+----------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------+
+|count(root.sg.a)|count(root.sg.b)|((((count(root.sg.a) + 1) * 2) - 1) % 2) + 1.5|(-count(root.sg.a) + count(root.sg.b) * (count(root.sg.a) * count(root.sg.b))) + (count(root.sg.a) / count(root.sg.b))|
++----------------+----------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------+
+| 4| 3| 2.5| -82.66666666666667|
++----------------+----------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------+
+Total line number = 1
+It costs 0.013s
+```
+
2. Aggregation with `GROUP BY`.
Input:
@@ -1158,8 +1180,8 @@ It costs 0.012s
> ```sql
> SELECT avg(s1+1) FROM root.sg.d1; -- The aggregation function has expression parameters.
> SELECT avg(s1) + avg(s2) FROM root.sg.* GROUP BY LEVEL=1; -- Grouped by level
-> SELECT avg(s1) + avg(s2) FROM root.sg.d1 GROUP BY([0, 10000), 1s) FILL(double [previous]); -- Automated fill
-> ```
+> SELECT avg(s1) + avg(s2) FROM root.sg.d1 GROUP BY([0, 10000), 1s) FILL(double [previous]); -- Automated fill
+> ```
### Automated Fill
@@ -1183,6 +1205,7 @@ Detailed descriptions of all parameters are given in Table 3-4.
**Table 3-4 Previous fill paramter list**
+
|Parameter name (case insensitive)|Interpretation|
|:---|:---|
|path, prefixPath|query path; mandatory field|
diff --git a/docs/zh/UserGuide/IoTDB-SQL-Language/DML-Data-Manipulation-Language.md b/docs/zh/UserGuide/IoTDB-SQL-Language/DML-Data-Manipulation-Language.md
index 79bb8c7..db90614 100644
--- a/docs/zh/UserGuide/IoTDB-SQL-Language/DML-Data-Manipulation-Language.md
+++ b/docs/zh/UserGuide/IoTDB-SQL-Language/DML-Data-Manipulation-Language.md
@@ -1089,14 +1089,13 @@ select count(status) from root.ln.wf01.wt01 group by ([0,20),2ms,3ms), level=1;
Total line number = 7
It costs 0.004s
```
-
#### 聚合查询嵌套表达式
IoTDB 支持在 `SELECT` 字句中执行由聚合查询和其他运算组成的任意嵌套表达式。
##### 示例
-不指定 `GROUP BY` 的聚合查询。
+1. 不指定 `GROUP BY` 的聚合查询。
输入:
@@ -1121,7 +1120,29 @@ Total line number = 1
It costs 0.009s
```
-指定 `GROUP BY` 的聚合查询。
+输入:
+
+```sql
+select count(a),
+ count(b),
+ ((count(a) + 1) * 2 - 1) % 2 + 1.5,
+ -(count(a) + count(b)) * (count(a) * count(b)) + count(a) / count(b)
+from root.sg;
+```
+
+结果:
+
+```
++----------------+----------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------+
+|count(root.sg.a)|count(root.sg.b)|((((count(root.sg.a) + 1) * 2) - 1) % 2) + 1.5|(-count(root.sg.a) + count(root.sg.b) * (count(root.sg.a) * count(root.sg.b))) + (count(root.sg.a) / count(root.sg.b))|
++----------------+----------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------+
+| 4| 3| 2.5| -82.66666666666667|
++----------------+----------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------+
+Total line number = 1
+It costs 0.013s
+```
+
+2. 指定 `GROUP BY` 的聚合查询。
输入:
@@ -1165,7 +1186,7 @@ It costs 0.012s
> SELECT avg(s1+1) FROM root.sg.d1; -- 聚合函数内部有表达式
> SELECT avg(s1) + avg(s2) FROM root.sg.* GROUP BY LEVEL=1; -- 按层级聚合
> SELECT avg(s1) + avg(s2) FROM root.sg.d1 GROUP BY([0, 10000), 1s) FILL(double [previous]); -- 空值填充
-> ```
+> ```
### 空值填充
diff --git a/integration/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBUserDefinedAggregationFunctionIT.java b/integration/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBUserDefinedAggregationFunctionIT.java
new file mode 100644
index 0000000..3e2fecc
--- /dev/null
+++ b/integration/src/test/java/org/apache/iotdb/db/integration/aggregation/IoTDBUserDefinedAggregationFunctionIT.java
@@ -0,0 +1,725 @@
+/*
+ * 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.integration.aggregation;
+
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.utils.EnvironmentUtils;
+import org.apache.iotdb.jdbc.Config;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Locale;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.fail;
+
+public class IoTDBUserDefinedAggregationFunctionIT {
+
+ private static final double DETLA = 1e-6;
+ private static final String TIMESTAMP_STR = "Time";
+ private static final String TEMPERATURE_STR = "root.ln.wf01.wt01.temperature";
+
+ private static String[] creationSqls =
+ new String[] {
+ "SET STORAGE GROUP TO root.vehicle.d0",
+ "SET STORAGE GROUP TO root.vehicle.d1",
+ "CREATE TIMESERIES root.vehicle.d0.s0 WITH DATATYPE=INT32, ENCODING=RLE",
+ "CREATE TIMESERIES root.vehicle.d0.s1 WITH DATATYPE=INT64, ENCODING=RLE",
+ "CREATE TIMESERIES root.vehicle.d0.s2 WITH DATATYPE=FLOAT, ENCODING=RLE",
+ "CREATE TIMESERIES root.vehicle.d0.s3 WITH DATATYPE=TEXT, ENCODING=PLAIN",
+ "CREATE TIMESERIES root.vehicle.d0.s4 WITH DATATYPE=BOOLEAN, ENCODING=PLAIN"
+ };
+ private static String[] dataSet2 =
+ new String[] {
+ "SET STORAGE GROUP TO root.ln.wf01.wt01",
+ "CREATE TIMESERIES root.ln.wf01.wt01.status WITH DATATYPE=BOOLEAN, ENCODING=PLAIN",
+ "CREATE TIMESERIES root.ln.wf01.wt01.temperature WITH DATATYPE=FLOAT, ENCODING=PLAIN",
+ "CREATE TIMESERIES root.ln.wf01.wt01.hardware WITH DATATYPE=INT32, ENCODING=PLAIN",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(1, 1.1, false, 11)",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(2, 2.2, true, 22)",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(3, 3.3, false, 33 )",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(4, 4.4, false, 44)",
+ "INSERT INTO root.ln.wf01.wt01(timestamp,temperature,status, hardware) "
+ + "values(5, 5.5, false, 55)"
+ };
+ private static String[] dataSet3 =
+ new String[] {
+ "SET STORAGE GROUP TO root.sg",
+ "CREATE TIMESERIES root.sg.d1.s1 WITH DATATYPE=INT32, ENCODING=RLE",
+ "insert into root.sg.d1(timestamp,s1) values(5,5)",
+ "insert into root.sg.d1(timestamp,s1) values(12,12)",
+ "flush",
+ "insert into root.sg.d1(timestamp,s1) values(15,15)",
+ "insert into root.sg.d1(timestamp,s1) values(25,25)",
+ "flush",
+ "insert into root.sg.d1(timestamp,s1) values(1,111)",
+ "insert into root.sg.d1(timestamp,s1) values(20,200)",
+ "flush"
+ };
+ private final String d0s0 = "root.vehicle.d0.s0";
+ private final String d0s1 = "root.vehicle.d0.s1";
+ private final String d0s2 = "root.vehicle.d0.s2";
+ private final String d0s3 = "root.vehicle.d0.s3";
+ private static final String insertTemplate =
+ "INSERT INTO root.vehicle.d0(timestamp,s0,s1,s2,s3,s4)" + " VALUES(%d,%d,%d,%f,%s,%s)";
+ private static long prevPartitionInterval =
+ IoTDBDescriptor.getInstance().getConfig().getPartitionInterval();
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ EnvironmentUtils.closeStatMonitor();
+ IoTDBDescriptor.getInstance().getConfig().setPartitionInterval(1000);
+ EnvironmentUtils.envSetUp();
+ Class.forName(Config.JDBC_DRIVER_NAME);
+ prepareData();
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ EnvironmentUtils.cleanEnv();
+ IoTDBDescriptor.getInstance().getConfig().setPartitionInterval(prevPartitionInterval);
+ }
+
+ // add test for part of points in page don't satisfy filter
+ // details in: https://issues.apache.org/jira/projects/IOTDB/issues/IOTDB-54
+ @Test
+ public void additionTest1() {
+ String[] retArray = new String[] {"0,3.0", "0,6.0,7.0", "0,4.0,6.0"};
+ try (Connection connection =
+ DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+
+ boolean hasResultSet =
+ statement.execute(
+ "SELECT count(temperature) + 1 FROM root.ln.wf01.wt01 WHERE hardware > 35");
+
+ Assert.assertTrue(hasResultSet);
+ int cnt;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans = resultSet.getString(TIMESTAMP_STR) + "," + resultSet.getString(1);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT count(temperature) + 1 FROM root.ln.wf01.wt01 WHERE hardware > 35 order by time desc");
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans = resultSet.getString(TIMESTAMP_STR) + "," + resultSet.getString(1);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT count(temperature) + min_time(temperature), count(temperature) + max_time(temperature) FROM root.ln.wf01.wt01 WHERE time > 3");
+
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + Double.valueOf(resultSet.getString(2)).toString();
+ Assert.assertEquals(retArray[cnt], ans);
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT count(temperature) + min_time(temperature), count(temperature) + max_time(temperature) FROM root.ln.wf01.wt01 WHERE time > 3 order by time desc ");
+
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(2, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT min_time(temperature), count(temperature) + min_time(temperature) FROM root.ln.wf01.wt01 WHERE time > 3");
+
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2);
+ cnt++;
+ }
+ Assert.assertEquals(3, cnt);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void addtionTest2() {
+ String[] retArray =
+ new String[] {
+ "0,2002.0,2003.0,2004.0,2005.0", "0,15000.0,7500,7500", "0,7500,15000.0,7500"
+ };
+ try (Connection connection =
+ DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+ boolean hasResultSet =
+ statement.execute(
+ "SELECT count(s0)+1,count(s1)+2,count(s2)+3,count(s3)+4 "
+ + "FROM root.vehicle.d0 WHERE time >= 6000 AND time <= 9000");
+
+ Assert.assertTrue(hasResultSet);
+ int cnt;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2)
+ + ","
+ + resultSet.getString(3)
+ + ","
+ + resultSet.getString(4);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+ // keep the correctness of `order by time desc`
+ hasResultSet =
+ statement.execute(
+ "SELECT count(s0)+1,count(s1)+2,count(s2)+3,count(s3)+4 "
+ + "FROM root.vehicle.d0 WHERE time >= 6000 AND time <= 9000 order by time desc");
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2)
+ + ","
+ + resultSet.getString(3)
+ + ","
+ + resultSet.getString(4);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT count(s0)+count(s1),count(s2),count(s3) " + "FROM root.vehicle.d0");
+
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 1;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2)
+ + ","
+ + resultSet.getString(3);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(2, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT count(s0)+count(s1),count(s2),count(s3) "
+ + "FROM root.vehicle.d0 order by time desc");
+
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 1;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2)
+ + ","
+ + resultSet.getString(3);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(2, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT count(s0),count(s0)+count(s1),count(s2) " + "FROM root.vehicle.d0");
+
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 2;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2)
+ + ","
+ + resultSet.getString(3);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(3, cnt);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void polyNominalWithFirstAndLastValueTest() {
+ String[] retArray = new String[] {"0,10001.0,2000"};
+ try (Connection connection =
+ DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+
+ boolean hasResultSet =
+ statement.execute(
+ "SELECT ((first_value(s0)+ last_value(s1))*2-first_value(s2)+2)/2, first_value(s1) "
+ + "FROM root.vehicle.d0 WHERE time >= 1500 AND time <= 9000");
+ Assert.assertTrue(hasResultSet);
+ int cnt;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT ((first_value(s0)+ last_value(s1))*2-first_value(s2)+2)/2, first_value(s1) "
+ + "FROM root.vehicle.d0 WHERE time >= 1500 AND time <= 9000 order by time desc");
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void polyNominalWithMaxMinTimeTest() {
+ String[] retArray = new String[] {"0,500,0.0", "0,100.0,2499", "0,-100.0,-2499"};
+ try (Connection connection =
+ DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+
+ boolean hasResultSet =
+ statement.execute(
+ "SELECT min_time(s2),((max_time(s0)+min_time(s2))*2+2)%10 "
+ + "FROM root.vehicle.d0 WHERE time >= 100 AND time < 9000");
+ Assert.assertTrue(hasResultSet);
+ int cnt;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT min_time(s2),((max_time(s0)+min_time(s2))*2+2)%10 "
+ + "FROM root.vehicle.d0 WHERE time >= 100 AND time < 9000 order by time desc");
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 0;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT ((max_time(s0)-min_time(s2))+1)/5,max_time(s0) "
+ + "FROM root.vehicle.d0 WHERE time <= 2500 AND time > 1800");
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 1;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(2, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT ((max_time(s0)-min_time(s2))+1)/5,max_time(s0) "
+ + "FROM root.vehicle.d0 WHERE time <= 2500 AND time > 1800 order by time desc");
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 1;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(2, cnt);
+ }
+ hasResultSet =
+ statement.execute(
+ "SELECT -((max_time(s0)-min_time(s2))+1)/5,-max_time(s0) "
+ + "FROM root.vehicle.d0 WHERE time <= 2500 AND time > 1800");
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 2;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(3, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT -((max_time(s0)-min_time(s2))+1)/5,-max_time(s0) "
+ + "FROM root.vehicle.d0 WHERE time <= 2500 AND time > 1800 order by time desc");
+ Assert.assertTrue(hasResultSet);
+ try (ResultSet resultSet = statement.getResultSet()) {
+ cnt = 2;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(1)
+ + ","
+ + resultSet.getString(2);
+ Assert.assertEquals(retArray[cnt], ans);
+ cnt++;
+ }
+ Assert.assertEquals(3, cnt);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void polynominalWithAvgAndSumTest() {
+ double[][] retArray = {
+ {0.0, 2.4508E7, 6250.374812593702},
+ {0.0, 626750.0, 1250.9980039920158}
+ };
+
+ try (Connection connection =
+ DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+
+ boolean hasResultSet =
+ statement.execute(
+ "SELECT sum(s0)+10000000,avg(s2)-1000"
+ + "FROM root.vehicle.d0 WHERE time >= 6000 AND time <= 9000");
+
+ Assert.assertTrue(hasResultSet);
+ int cnt = 0;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ while (resultSet.next()) {
+ double[] ans = new double[3];
+ ans[0] = Double.valueOf(resultSet.getString(TIMESTAMP_STR));
+ ans[1] = Double.valueOf(resultSet.getString(1));
+ ans[2] = Double.valueOf(resultSet.getString(2));
+ assertArrayEquals(retArray[cnt], ans, DETLA);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+ // keep the correctness of `order by time desc`
+ hasResultSet =
+ statement.execute(
+ "SELECT sum(s0)+10000000,avg(s2)-1000"
+ + "FROM root.vehicle.d0 WHERE time >= 6000 AND time <= 9000 order by time desc");
+
+ Assert.assertTrue(hasResultSet);
+ cnt = 0;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ while (resultSet.next()) {
+ double[] ans = new double[3];
+ ans[0] = Double.valueOf(resultSet.getString(TIMESTAMP_STR));
+ ans[1] = Double.valueOf(resultSet.getString(1));
+ ans[2] = Double.valueOf(resultSet.getString(2));
+ assertArrayEquals(retArray[cnt], ans, DETLA);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ hasResultSet =
+ statement.execute(
+ "SELECT (sum(s0)+15)-3*5,avg(s2)"
+ + "FROM root.vehicle.d0 WHERE time >= 1000 AND time <= 2000");
+ Assert.assertTrue(hasResultSet);
+ cnt = 1;
+ try (ResultSet resultSet = statement.getResultSet()) {
+ while (resultSet.next()) {
+ double[] ans = new double[3];
+ ans[0] = Double.valueOf(resultSet.getString(TIMESTAMP_STR));
+ ans[1] = Double.valueOf(resultSet.getString(1));
+ ans[2] = Double.valueOf(resultSet.getString(2));
+ assertArrayEquals(retArray[cnt], ans, DETLA);
+ cnt++;
+ }
+ Assert.assertEquals(2, cnt);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void avgSumErrorTest() {
+ try (Connection connection =
+ DriverManager.getConnection("jdbc:iotdb://127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+ try {
+ statement.execute(
+ "SELECT avg(s3)+1" + "FROM root.vehicle.d0 WHERE time >= 6000 AND time <= 9000");
+ try (ResultSet resultSet = statement.getResultSet()) {
+ resultSet.next();
+ fail();
+ }
+ } catch (Exception e) {
+ Assert.assertTrue(
+ e.getMessage().contains("Unsupported data type in aggregation AVG : TEXT"));
+ }
+ try {
+ statement.execute(
+ "SELECT sum(s3)+1" + "FROM root.vehicle.d0 WHERE time >= 6000 AND time <= 9000");
+ try (ResultSet resultSet = statement.getResultSet()) {
+ resultSet.next();
+ fail();
+ }
+ } catch (Exception e) {
+ Assert.assertTrue(
+ e.getMessage().contains("Unsupported data type in aggregation SUM : TEXT"));
+ }
+ try {
+ statement.execute(
+ "SELECT avg(s4)+1" + "FROM root.vehicle.d0 WHERE time >= 6000 AND time <= 9000");
+ try (ResultSet resultSet = statement.getResultSet()) {
+ resultSet.next();
+ fail();
+ }
+ } catch (Exception e) {
+ Assert.assertTrue(
+ e.getMessage().contains("Unsupported data type in aggregation AVG : BOOLEAN"));
+ }
+ try {
+ statement.execute(
+ "SELECT sum(s4)+1" + "FROM root.vehicle.d0 WHERE time >= 6000 AND time <= 9000");
+ try (ResultSet resultSet = statement.getResultSet()) {
+ resultSet.next();
+ fail();
+ }
+ } catch (Exception e) {
+ Assert.assertTrue(
+ e.getMessage().contains("Unsupported data type in aggregation SUM : BOOLEAN"));
+ }
+ try {
+ statement.execute("SELECT avg(status)+2 FROM root.ln.wf01.wt01");
+ try (ResultSet resultSet = statement.getResultSet()) {
+ resultSet.next();
+ fail();
+ }
+ } catch (Exception e) {
+ Assert.assertTrue(e.getMessage().contains("Boolean statistics does not support: avg"));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ private static void prepareData() {
+ try (Connection connection =
+ DriverManager.getConnection(
+ Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+ Statement statement = connection.createStatement()) {
+
+ for (String sql : creationSqls) {
+ statement.execute(sql);
+ }
+
+ // prepare BufferWrite file
+ for (int i = 5000; i < 7000; i++) {
+ statement.execute(
+ String.format(
+ Locale.ENGLISH, insertTemplate, i, i, i, (double) i, "'" + i + "'", "true"));
+ }
+ statement.execute("FLUSH");
+ for (int i = 7500; i < 8500; i++) {
+ statement.execute(
+ String.format(
+ Locale.ENGLISH, insertTemplate, i, i, i, (double) i, "'" + i + "'", "false"));
+ }
+ statement.execute("FLUSH");
+ // prepare Unseq-File
+ for (int i = 500; i < 1500; i++) {
+ statement.execute(
+ String.format(
+ Locale.ENGLISH, insertTemplate, i, i, i, (double) i, "'" + i + "'", "true"));
+ }
+ statement.execute("FLUSH");
+ for (int i = 3000; i < 6500; i++) {
+ statement.execute(
+ String.format(
+ Locale.ENGLISH, insertTemplate, i, i, i, (double) i, "'" + i + "'", "false"));
+ }
+ statement.execute("merge");
+
+ // prepare BufferWrite cache
+ for (int i = 9000; i < 10000; i++) {
+ statement.execute(
+ String.format(
+ Locale.ENGLISH, insertTemplate, i, i, i, (double) i, "'" + i + "'", "true"));
+ }
+ // prepare Overflow cache
+ for (int i = 2000; i < 2500; i++) {
+ statement.execute(
+ String.format(
+ Locale.ENGLISH, insertTemplate, i, i, i, (double) i, "'" + i + "'", "false"));
+ }
+
+ for (String sql : dataSet3) {
+ statement.execute(sql);
+ }
+
+ for (String sql : dataSet2) {
+ statement.execute(sql);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
index 0082c20..134d57d 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
@@ -133,7 +133,7 @@ public class QueryOperator extends Operator {
}
public boolean hasAggregationFunction() {
- return selectComponent.hasAggregationFunction();
+ return selectComponent.hasPlainAggregationFunction();
}
public boolean hasTimeSeriesGeneratingFunction() {
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
index aed3727..f06d661 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/SelectComponent.java
@@ -34,7 +34,7 @@ public final class SelectComponent {
private final ZoneId zoneId;
- private boolean hasAggregationFunction = false;
+ private boolean hasPlainAggregationFunction = false;
private boolean hasTimeSeriesGeneratingFunction = false;
private boolean hasUserDefinedAggregationFunction = false;
@@ -50,7 +50,7 @@ public final class SelectComponent {
public SelectComponent(SelectComponent selectComponent) {
zoneId = selectComponent.zoneId;
- hasAggregationFunction = selectComponent.hasAggregationFunction;
+ hasPlainAggregationFunction = selectComponent.hasPlainAggregationFunction;
hasTimeSeriesGeneratingFunction = selectComponent.hasTimeSeriesGeneratingFunction;
resultColumns.addAll(selectComponent.resultColumns);
}
@@ -59,8 +59,12 @@ public final class SelectComponent {
return zoneId;
}
- public boolean hasAggregationFunction() {
- return hasAggregationFunction;
+ public void setHasPlainAggregationFunction(boolean hasPlainAggregationFunction) {
+ this.hasPlainAggregationFunction = hasPlainAggregationFunction;
+ }
+
+ public boolean hasPlainAggregationFunction() {
+ return hasPlainAggregationFunction;
}
public boolean hasTimeSeriesGeneratingFunction() {
@@ -73,12 +77,11 @@ public final class SelectComponent {
public void addResultColumn(ResultColumn resultColumn) {
resultColumns.add(resultColumn);
- if (resultColumn.getExpression().isUDAFExpression()) {
+ if (resultColumn.getExpression().isUserDefinedAggregationFunctionExpression()) {
hasUserDefinedAggregationFunction = true;
}
-
- if (resultColumn.getExpression().isAggregationFunctionExpression()) {
- hasAggregationFunction = true;
+ if (resultColumn.getExpression().isPlainAggregationFunctionExpression()) {
+ hasPlainAggregationFunction = true;
}
if (resultColumn.getExpression().isTimeSeriesGeneratingFunctionExpression()) {
hasTimeSeriesGeneratingFunction = true;
@@ -104,7 +107,7 @@ public final class SelectComponent {
if (expression instanceof TimeSeriesOperand) {
pathsCache.add(((TimeSeriesOperand) expression).getPath());
} else if (expression instanceof FunctionExpression
- && expression.isAggregationFunctionExpression()) {
+ && expression.isPlainAggregationFunctionExpression()) {
pathsCache.add(
((TimeSeriesOperand) ((FunctionExpression) expression).getExpressions().get(0))
.getPath());
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDAFQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDAFQueryOperator.java
index d6a14bd..5f61fdb 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDAFQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDAFQueryOperator.java
@@ -32,23 +32,24 @@ import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
/**
* For a UDAFPlan, we construct an inner AggregationPlan for it. Example: select
* count(a)/count(b),count(a)+sum(b) from root.sg To init inner AggregationPlan, we will convert it
- * to statement: select count(a),count(b),count(a),sum(b) from root.sg. innerResultColumnsCache will
- * be [count(a),count(b),sum(b)].
+ * to statement: select count(a),count(b),count(a),sum(b) from root.sg innerResultColumnsCache will
+ * be [count(a),count(b),sum(b)]
*/
public class UDAFQueryOperator extends QueryOperator {
- private ArrayList<ResultColumn> innerResultColumnsCache;
+ private List<ResultColumn> innerResultColumnsCache;
- private AggregationQueryOperator aggrOp;
+ private AggregationQueryOperator innerAggregationQueryOperator;
public UDAFQueryOperator(AggregationQueryOperator queryOperator) {
super(queryOperator);
- this.aggrOp = queryOperator;
+ this.innerAggregationQueryOperator = queryOperator;
}
@Override
@@ -63,7 +64,7 @@ public class UDAFQueryOperator extends QueryOperator {
throw new LogicalOperatorException(
"UDF nesting aggregations in GROUP BY query does not support grouping by level now.");
}
- if (aggrOp instanceof GroupByFillQueryOperator) {
+ if (innerAggregationQueryOperator instanceof GroupByFillQueryOperator) {
throw new LogicalOperatorException(
"UDF nesting aggregations in GROUP BY query does not support FILL now.");
}
@@ -77,7 +78,7 @@ public class UDAFQueryOperator extends QueryOperator {
}
}
- public ArrayList<ResultColumn> getInnerResultColumnsCache() {
+ public List<ResultColumn> getInnerResultColumnsCache() {
if (innerResultColumnsCache == null) {
innerResultColumnsCache = new ArrayList<>();
for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
@@ -91,7 +92,7 @@ public class UDAFQueryOperator extends QueryOperator {
private void addInnerResultColumn(Expression expression) {
for (Iterator<Expression> it = expression.iterator(); it.hasNext(); ) {
Expression currentExp = it.next();
- if (currentExp.isAggregationFunctionExpression()) {
+ if (currentExp.isPlainAggregationFunctionExpression()) {
innerResultColumnsCache.add(new ResultColumn(currentExp));
}
}
@@ -100,16 +101,7 @@ public class UDAFQueryOperator extends QueryOperator {
@Override
public PhysicalPlan generatePhysicalPlan(PhysicalGenerator generator)
throws QueryProcessException {
- SelectComponent copiedSelectComponent = new SelectComponent(getSelectComponent());
- copiedSelectComponent.setResultColumns(getInnerResultColumnsCache());
- aggrOp.setSelectComponent(copiedSelectComponent);
- aggrOp.setFromComponent(getFromComponent());
- aggrOp.setWhereComponent(getWhereComponent());
- aggrOp.setSpecialClauseComponent(getSpecialClauseComponent());
- aggrOp.setProps(getProps());
- aggrOp.setIndexType(getIndexType());
- aggrOp.setEnableTracing(isEnableTracing());
- AggregationPlan innerAggregationPlan = (AggregationPlan) aggrOp.generatePhysicalPlan(generator);
+ AggregationPlan innerAggregationPlan = initInnerAggregationPlan(generator);
PhysicalPlan physicalPlan;
if (!isAlignByDevice()) {
physicalPlan =
@@ -151,12 +143,27 @@ public class UDAFQueryOperator extends QueryOperator {
return physicalPlan;
}
+ private AggregationPlan initInnerAggregationPlan(PhysicalGenerator generator)
+ throws QueryProcessException {
+ SelectComponent copiedSelectComponent = new SelectComponent(getSelectComponent());
+ copiedSelectComponent.setHasPlainAggregationFunction(true);
+ copiedSelectComponent.setResultColumns(getInnerResultColumnsCache());
+ innerAggregationQueryOperator.setSelectComponent(copiedSelectComponent);
+ innerAggregationQueryOperator.setFromComponent(getFromComponent());
+ innerAggregationQueryOperator.setWhereComponent(getWhereComponent());
+ innerAggregationQueryOperator.setSpecialClauseComponent(getSpecialClauseComponent());
+ innerAggregationQueryOperator.setProps(getProps());
+ innerAggregationQueryOperator.setIndexType(getIndexType());
+ innerAggregationQueryOperator.setEnableTracing(isEnableTracing());
+ return (AggregationPlan) innerAggregationQueryOperator.generatePhysicalPlan(generator);
+ }
+
private void checkEachExpression(Expression expression) throws LogicalOperatorException {
if (expression instanceof TimeSeriesOperand) {
throw new LogicalOperatorException(AggregationQueryOperator.ERROR_MESSAGE1);
}
// Currently, the aggregation function expression can only contain a timeseries operand.
- if (expression.isAggregationFunctionExpression()) {
+ if (expression.isPlainAggregationFunctionExpression()) {
if (expression.getExpressions().size() == 1
&& expression.getExpressions().get(0) instanceof TimeSeriesOperand) {
return;
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDFQueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDTFQueryOperator.java
similarity index 91%
rename from server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDFQueryOperator.java
rename to server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDTFQueryOperator.java
index 4b6fdfe..df0c131 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDFQueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/UDTFQueryOperator.java
@@ -24,13 +24,13 @@ import org.apache.iotdb.db.qp.physical.PhysicalPlan;
import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
import org.apache.iotdb.db.qp.strategy.PhysicalGenerator;
-public class UDFQueryOperator extends QueryOperator {
+public class UDTFQueryOperator extends QueryOperator {
- public UDFQueryOperator() {
+ public UDTFQueryOperator() {
super();
}
- public UDFQueryOperator(QueryOperator queryOperator) {
+ public UDTFQueryOperator(QueryOperator queryOperator) {
super(queryOperator);
}
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 2f891d3..c5de0d0 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
@@ -50,7 +50,7 @@ import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
import org.apache.iotdb.db.qp.logical.crud.SelectIntoOperator;
import org.apache.iotdb.db.qp.logical.crud.SpecialClauseComponent;
import org.apache.iotdb.db.qp.logical.crud.UDAFQueryOperator;
-import org.apache.iotdb.db.qp.logical.crud.UDFQueryOperator;
+import org.apache.iotdb.db.qp.logical.crud.UDTFQueryOperator;
import org.apache.iotdb.db.qp.logical.crud.WhereComponent;
import org.apache.iotdb.db.qp.logical.sys.ActivateTemplateOperator;
import org.apache.iotdb.db.qp.logical.sys.AlterTimeSeriesOperator;
@@ -2531,14 +2531,14 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
for (IoTDBSqlParser.ResultColumnContext resultColumnContext : ctx.resultColumn()) {
selectComponent.addResultColumn(parseResultColumn(resultColumnContext));
}
-
+ // judge query type
if (!hasDecidedQueryType()) {
if (selectComponent.hasUserDefinedAggregationFunction()) {
queryOp = new UDAFQueryOperator(new AggregationQueryOperator(queryOp));
- } else if (selectComponent.hasAggregationFunction()) {
+ } else if (selectComponent.hasPlainAggregationFunction()) {
queryOp = new AggregationQueryOperator(queryOp);
} else if (selectComponent.hasTimeSeriesGeneratingFunction()) {
- queryOp = new UDFQueryOperator(queryOp);
+ queryOp = new UDTFQueryOperator(queryOp);
}
} else if (selectComponent.hasUserDefinedAggregationFunction()) {
queryOp = new UDAFQueryOperator((AggregationQueryOperator) (queryOp));
@@ -2717,7 +2717,8 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
|| queryOp instanceof FillQueryOperator
|| queryOp instanceof LastQueryOperator
|| queryOp instanceof AggregationQueryOperator
- || queryOp instanceof UDFQueryOperator;
+ || queryOp instanceof UDTFQueryOperator
+ || queryOp instanceof UDAFQueryOperator;
}
private String parseStringWithQuotes(String src) {
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 48556cd..8c09b2b 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
@@ -76,7 +76,7 @@ public class GroupByLevelController {
for (Iterator<Expression> it = rawColumn.getExpression().iterator(); it.hasNext(); ) {
Expression expression = it.next();
if (expression instanceof FunctionExpression
- && expression.isAggregationFunctionExpression()
+ && expression.isPlainAggregationFunctionExpression()
&& ((FunctionExpression) expression).isCountStar()) {
countWildcardIterIndices.add(idx);
}
@@ -93,7 +93,7 @@ public class GroupByLevelController {
for (Iterator<Expression> it = rootExpression.iterator(); it.hasNext(); ) {
Expression expression = it.next();
if (expression instanceof FunctionExpression
- && expression.isAggregationFunctionExpression()) {
+ && expression.isPlainAggregationFunctionExpression()) {
hasAggregation = true;
List<PartialPath> paths = ((FunctionExpression) expression).getPaths();
String functionName = ((FunctionExpression) expression).getFunctionName();
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java
index 0bf537d..92bd9bc 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java
@@ -46,11 +46,11 @@ public abstract class Expression {
private String expressionStringCache;
protected Boolean isConstantOperandCache = null;
- public boolean isAggregationFunctionExpression() {
+ public boolean isPlainAggregationFunctionExpression() {
return false;
}
- public boolean isUDAFExpression() {
+ public boolean isUserDefinedAggregationFunctionExpression() {
return false;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/BinaryExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/BinaryExpression.java
index f5e1d23..c30e56f 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/BinaryExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/BinaryExpression.java
@@ -69,15 +69,15 @@ public abstract class BinaryExpression extends Expression {
@Override
public boolean isTimeSeriesGeneratingFunctionExpression() {
- return !isUDAFExpression();
+ return !isUserDefinedAggregationFunctionExpression();
}
@Override
- public boolean isUDAFExpression() {
- return leftExpression.isAggregationFunctionExpression()
- || rightExpression.isAggregationFunctionExpression()
- || leftExpression.isUDAFExpression()
- || rightExpression.isUDAFExpression();
+ public boolean isUserDefinedAggregationFunctionExpression() {
+ return leftExpression.isPlainAggregationFunctionExpression()
+ || rightExpression.isPlainAggregationFunctionExpression()
+ || leftExpression.isUserDefinedAggregationFunctionExpression()
+ || rightExpression.isUserDefinedAggregationFunctionExpression();
}
@Override
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/FunctionExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/FunctionExpression.java
index 885f2bd..cb18570 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/FunctionExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/FunctionExpression.java
@@ -60,9 +60,9 @@ public class FunctionExpression extends Expression {
* true: aggregation function<br>
* false: time series generating function
*/
- private final boolean isAggregationFunctionExpression;
+ private final boolean isPlainAggregationFunctionExpression;
- private boolean isUDAFExpression;
+ private boolean isUserDefinedAggregationFunctionExpression;
private final String functionName;
private final Map<String, String> functionAttributes;
@@ -82,7 +82,7 @@ public class FunctionExpression extends Expression {
this.functionName = functionName;
functionAttributes = new LinkedHashMap<>();
expressions = new ArrayList<>();
- isAggregationFunctionExpression =
+ isPlainAggregationFunctionExpression =
SQLConstant.getNativeFunctionNames().contains(functionName.toLowerCase());
isConstantOperandCache = true;
}
@@ -92,17 +92,20 @@ public class FunctionExpression extends Expression {
this.functionName = functionName;
this.functionAttributes = functionAttributes;
this.expressions = expressions;
- isAggregationFunctionExpression =
+ isPlainAggregationFunctionExpression =
SQLConstant.getNativeFunctionNames().contains(functionName.toLowerCase());
isConstantOperandCache = expressions.stream().anyMatch(Expression::isConstantOperand);
- isUDAFExpression =
+ isUserDefinedAggregationFunctionExpression =
expressions.stream()
- .anyMatch(v -> v.isUDAFExpression() || v.isAggregationFunctionExpression());
+ .anyMatch(
+ v ->
+ v.isUserDefinedAggregationFunctionExpression()
+ || v.isPlainAggregationFunctionExpression());
}
@Override
- public boolean isAggregationFunctionExpression() {
- return isAggregationFunctionExpression;
+ public boolean isPlainAggregationFunctionExpression() {
+ return isPlainAggregationFunctionExpression;
}
@Override
@@ -111,13 +114,13 @@ public class FunctionExpression extends Expression {
}
@Override
- public boolean isUDAFExpression() {
- return isUDAFExpression;
+ public boolean isTimeSeriesGeneratingFunctionExpression() {
+ return !isPlainAggregationFunctionExpression() && !isUserDefinedAggregationFunctionExpression();
}
@Override
- public boolean isTimeSeriesGeneratingFunctionExpression() {
- return !isAggregationFunctionExpression;
+ public boolean isUserDefinedAggregationFunctionExpression() {
+ return isUserDefinedAggregationFunctionExpression;
}
public boolean isCountStar() {
@@ -132,10 +135,10 @@ public class FunctionExpression extends Expression {
public void addExpression(Expression expression) {
isConstantOperandCache = isConstantOperandCache && expression.isConstantOperand();
- isUDAFExpression =
- isUDAFExpression
- || expression.isUDAFExpression()
- || expression.isAggregationFunctionExpression();
+ isUserDefinedAggregationFunctionExpression =
+ isUserDefinedAggregationFunctionExpression
+ || expression.isUserDefinedAggregationFunctionExpression()
+ || expression.isPlainAggregationFunctionExpression();
expressions.add(expression);
}
@@ -151,6 +154,7 @@ public class FunctionExpression extends Expression {
return functionAttributes;
}
+ @Override
public List<Expression> getExpressions() {
return expressions;
}
@@ -224,7 +228,7 @@ public class FunctionExpression extends Expression {
if (!expressionIntermediateLayerMap.containsKey(this)) {
float memoryBudgetInMB = memoryAssigner.assign();
Transformer transformer;
- if (isAggregationFunctionExpression) {
+ if (isPlainAggregationFunctionExpression) {
transformer =
new TransparentTransformer(
rawTimeSeriesInputLayer.constructPointReader(
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
index ced0532..43c6dc5 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
@@ -67,12 +67,13 @@ public class NegationExpression extends Expression {
@Override
public boolean isTimeSeriesGeneratingFunctionExpression() {
- return true;
+ return !isUserDefinedAggregationFunctionExpression();
}
@Override
- public boolean isUDAFExpression() {
- return expression.isUDAFExpression() || expression.isAggregationFunctionExpression();
+ public boolean isUserDefinedAggregationFunctionExpression() {
+ return expression.isUserDefinedAggregationFunctionExpression()
+ || expression.isPlainAggregationFunctionExpression();
}
@Override