This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch ty/TableIT
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/ty/TableIT by this push:
new a22fe7c72b1 Add IT for IoTDBDatetimeFormatIT and IoTDBNestedQueryIT
a22fe7c72b1 is described below
commit a22fe7c72b103fbea8b87d64a9579fe63b87818b
Author: JackieTien97 <[email protected]>
AuthorDate: Wed Jul 24 12:20:33 2024 +0800
Add IT for IoTDBDatetimeFormatIT and IoTDBNestedQueryIT
---
.../scalar/IoTDBDiffFunctionIT.java | 367 ++++++++++------
.../it/query/old/IoTDBDatetimeFormatIT.java | 157 +++++++
.../it/query/old/IoTDBNestedQueryIT.java | 460 +++++++++++++++++++++
.../scalar/IoTDBDiffFunctionIT.java | 348 +++++-----------
.../plan/relational/analyzer/Analyzer.java | 4 +
.../predicate/ConvertPredicateToFilterVisitor.java | 9 +-
.../planner/ir/NormalizeOrExpressionRewriter.java | 15 +-
.../plan/relational/sql/parser/AstBuilder.java | 17 +
.../db/relational/grammar/sql/RelationalSql.g4 | 6 +-
9 files changed, 1008 insertions(+), 375 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/builtinfunction/scalar/IoTDBDiffFunctionIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/builtinfunction/scalar/IoTDBDiffFunctionIT.java
index 77f90aa993a..970bbc2a745 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/builtinfunction/scalar/IoTDBDiffFunctionIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/builtinfunction/scalar/IoTDBDiffFunctionIT.java
@@ -23,7 +23,6 @@ import org.apache.iotdb.it.env.EnvFactory;
import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.ClusterIT;
import org.apache.iotdb.itbase.category.LocalStandaloneIT;
-import org.apache.iotdb.itbase.env.BaseEnv;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -31,35 +30,33 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
-import java.sql.Connection;
-import java.sql.Statement;
-
+import static org.apache.iotdb.db.it.utils.TestUtils.prepareData;
import static org.apache.iotdb.db.it.utils.TestUtils.resultSetEqualTest;
+import static org.apache.iotdb.itbase.constant.TestConstant.DEVICE;
+import static org.apache.iotdb.itbase.constant.TestConstant.TIMESTAMP_STR;
@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class, ClusterIT.class})
public class IoTDBDiffFunctionIT {
-
- private static final String DATABASE_NAME = "db";
-
- // 2 devices 4 regions
protected static final String[] SQLs =
new String[] {
- "CREATE DATABASE " + DATABASE_NAME,
- "use " + DATABASE_NAME,
- "create table table1(device_id STRING ID, s1 INT32 MEASUREMENT, FLOAT
INT32 MEASUREMENT);",
- "INSERT INTO table1(time,device_id,s1,s2) values(1, 'd1', 1, 1)",
- "INSERT INTO table1(time,device_id,s1) values(2, 'd1', 2)",
- "INSERT INTO table1(time,device_id,s2) values(3, 'd1', 3)",
- "INSERT INTO table1(time,device_id,s1) values(4, 'd1', 4)",
- "INSERT INTO table1(time,device_id,s1,s2) values(5, 'd1', 5, 5)",
- "INSERT INTO table1(time,device_id,s2) values(6, 'd1', 6)",
- "INSERT INTO table1(time,device_id,s1,s2) values(5000000000, 'd1',
null, 7)",
- "INSERT INTO table1(time,device_id,s1,s2) values(5000000001, 'd1', 8,
null)",
- "INSERT INTO table1(time,device_id,s1,s2) values(1, 'd2', 1, 1)",
- "INSERT INTO table1(time,device_id,s1,s2) values(2, 'd2', 2, 2)",
- "INSERT INTO table1(time,device_id,s1,s2) values(5000000000, 'd2',
null, 3)",
- "INSERT INTO table1(time,device_id,s1,s2) values(5000000001, 'd2', 4,
null)",
+ "CREATE DATABASE root.db",
+ "CREATE TIMESERIES root.db.d1.s1 WITH DATATYPE=INT32, ENCODING=PLAIN",
+ "CREATE TIMESERIES root.db.d1.s2 WITH DATATYPE=FLOAT, ENCODING=PLAIN",
+ "INSERT INTO root.db.d1(timestamp,s1,s2) values(1, 1, 1)",
+ "INSERT INTO root.db.d1(timestamp,s1) values(2, 2)",
+ "INSERT INTO root.db.d1(timestamp,s2) values(3, 3)",
+ "INSERT INTO root.db.d1(timestamp,s1) values(4, 4)",
+ "INSERT INTO root.db.d1(timestamp,s1,s2) values(5, 5, 5)",
+ "INSERT INTO root.db.d1(timestamp,s2) values(6, 6)",
+ "INSERT INTO root.db.d1(timestamp,s1,s2) values(5000000000, null, 7)",
+ "INSERT INTO root.db.d1(timestamp,s1,s2) values(5000000001, 8, null)",
+ "CREATE TIMESERIES root.db.d2.s1 WITH DATATYPE=INT32, ENCODING=PLAIN",
+ "CREATE TIMESERIES root.db.d2.s2 WITH DATATYPE=FLOAT, ENCODING=PLAIN",
+ "INSERT INTO root.db.d2(timestamp,s1,s2) values(1, 1, 1)",
+ "INSERT INTO root.db.d2(timestamp,s1,s2) values(2, 2, 2)",
+ "INSERT INTO root.db.d2(timestamp,s1,s2) values(5000000000, null, 3)",
+ "INSERT INTO root.db.d2(timestamp,s1,s2) values(5000000001, 4, null)",
"flush"
};
@@ -67,19 +64,7 @@ public class IoTDBDiffFunctionIT {
public static void setUp() throws Exception {
EnvFactory.getEnv().getConfig().getCommonConfig().setPartitionInterval(1000);
EnvFactory.getEnv().initClusterEnvironment();
- insertData();
- }
-
- protected static void insertData() {
- try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
- Statement statement = connection.createStatement()) {
-
- for (String sql : SQLs) {
- statement.execute(sql);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
+ prepareData(SQLs);
}
@AfterClass
@@ -89,141 +74,285 @@ public class IoTDBDiffFunctionIT {
@Test
public void testNewTransformerIgnoreNull() {
- String[] expectedHeader = new String[] {"time", "_col1", "_col2"};
+ String[] expectedHeader =
+ new String[] {TIMESTAMP_STR, "Diff(root.db.d1.s1)",
"diff(root.db.d1.s2)"};
String[] retArray =
new String[] {
- "1997-01-01T08:00:00.001Z,null,null,",
- "1997-01-01T08:00:00.002Z,1.0,null,",
- "1997-01-01T08:00:00.003Z,null,2.0,",
- "1997-01-01T08:00:00.004Z,2.0,null,",
- "1997-01-01T08:00:00.005Z,1.0,2.0,",
- "1997-01-01T08:00:00.006Z,null,1.0,",
- "1970-02-27T20:53:20.000Z,null,1.0,",
- "1970-02-27T20:53:20.001Z,3.0,null,"
+ "1,null,null,",
+ "2,1.0,null,",
+ "3,null,2.0,",
+ "4,2.0,null,",
+ "5,1.0,2.0,",
+ "6,null,1.0,",
+ "5000000000,null,1.0,",
+ "5000000001,3.0,null,"
};
- resultSetEqualTest(
- "select time,diff(s1), diff(s2) from table1 where device_id='d1'",
- expectedHeader,
- retArray);
+ resultSetEqualTest("select Diff(s1), diff(s2) from root.db.d1",
expectedHeader, retArray);
// align by device
- expectedHeader = new String[] {"time", "device_id", "_col1", "_col2"};
+ expectedHeader = new String[] {TIMESTAMP_STR, DEVICE, "Diff(s1)",
"diff(s2)"};
retArray =
new String[] {
- "1997-01-01T08:00:00.001Z,d1,null,null,",
- "1997-01-01T08:00:00.002Z,d1,1.0,null,",
- "1997-01-01T08:00:00.003Z,d1,null,2.0,",
- "1997-01-01T08:00:00.004Z,d1,2.0,null,",
- "1997-01-01T08:00:00.005Z,d1,1.0,2.0,",
- "1997-01-01T08:00:00.006Z,d1,null,1.0,",
- "1970-02-27T20:53:20.000Z,d1,null,1.0,",
- "1970-02-27T20:53:20.001Z,d1,3.0,null,",
- "1997-01-01T08:00:00.001Z,d2,null,null",
- "1997-01-01T08:00:00.002Z,d2,1.0,1.0,",
- "1970-02-27T20:53:20.000Z,d2,null,1.0,",
- "1970-02-27T20:53:20.001Z,d2,2.0,null,",
+ "1,root.db.d1,null,null,",
+ "2,root.db.d1,1.0,null,",
+ "3,root.db.d1,null,2.0,",
+ "4,root.db.d1,2.0,null,",
+ "5,root.db.d1,1.0,2.0,",
+ "6,root.db.d1,null,1.0,",
+ "5000000000,root.db.d1,null,1.0,",
+ "5000000001,root.db.d1,3.0,null,",
+ "1,root.db.d2,null,null,",
+ "2,root.db.d2,1.0,1.0,",
+ "5000000000,root.db.d2,null,1.0,",
+ "5000000001,root.db.d2,2.0,null,"
};
resultSetEqualTest(
- "select time, device_id, Diff(s1), diff(s2) from table1 where
device_id='d1' or device_id='d2' order by device_id",
+ "select Diff(s1), diff(s2) from root.db.d1, root.db.d2 align by
device",
expectedHeader,
retArray);
// align by device + order by time
retArray =
new String[] {
- "1997-01-01T08:00:00.001Z,d1,null,null,",
- "1997-01-01T08:00:00.001Z,d2,null,null",
- "1997-01-01T08:00:00.002Z,d1,1.0,null,",
- "1997-01-01T08:00:00.002Z,d2,1.0,1.0,",
- "1997-01-01T08:00:00.003Z,d1,null,2.0,",
- "1997-01-01T08:00:00.004Z,d1,2.0,null,",
- "1997-01-01T08:00:00.005Z,d1,1.0,2.0,",
- "1997-01-01T08:00:00.006Z,d1,null,1.0,",
- "1970-02-27T20:53:20.000Z,d1,null,1.0,",
- "1970-02-27T20:53:20.000Z,d2,null,1.0,",
- "1970-02-27T20:53:20.001Z,d1,3.0,null,",
- "1970-02-27T20:53:20.001Z,d2,2.0,null,",
+ "1,root.db.d1,null,null,",
+ "1,root.db.d2,null,null,",
+ "2,root.db.d1,1.0,null,",
+ "2,root.db.d2,1.0,1.0,",
+ "3,root.db.d1,null,2.0,",
+ "4,root.db.d1,2.0,null,",
+ "5,root.db.d1,1.0,2.0,",
+ "6,root.db.d1,null,1.0,",
+ "5000000000,root.db.d1,null,1.0,",
+ "5000000000,root.db.d2,null,1.0,",
+ "5000000001,root.db.d1,3.0,null,",
+ "5000000001,root.db.d2,2.0,null,"
};
resultSetEqualTest(
- "select time, device_id, Diff(s1), diff(s2) from table1 where
device_id='d1' or device_id='d2' order by time,device_id",
+ "select Diff(s1), diff(s2) from root.db.d1, root.db.d2 order by time
align by device",
expectedHeader,
retArray);
}
@Test
public void testNewTransformerRespectNull() {
- String[] expectedHeader = new String[] {"time", "_col1", "_col2"};
+ String[] expectedHeader =
+ new String[] {
+ TIMESTAMP_STR,
+ "Diff(root.db.d1.s1, \"ignoreNull\"=\"false\")",
+ "diff(root.db.d1.s2, \"ignoreNull\"=\"false\")"
+ };
String[] retArray =
new String[] {
- "1997-01-01T08:00:00.001Z,null,null,",
- "1997-01-01T08:00:00.002Z,1.0,null,",
- "1997-01-01T08:00:00.003Z,null,null,",
- "1997-01-01T08:00:00.004Z,null,null,",
- "1997-01-01T08:00:00.005Z,1.0,null,",
- "1997-01-01T08:00:00.006Z,null,1.0,",
- "1970-02-27T20:53:20.000Z,null,1.0,",
- "1970-02-27T20:53:20.001Z,null,null,"
+ "1,null,null,",
+ "2,1.0,null,",
+ "3,null,null,",
+ "4,null,null,",
+ "5,1.0,null,",
+ "6,null,1.0,",
+ "5000000000,null,1.0,",
+ "5000000001,null,null,"
};
resultSetEqualTest(
- "select time, Diff(s1, false), diff(s2, false) from table1 where
device_id='d1'",
+ "select Diff(s1, 'ignoreNull'='false'), diff(s2, 'ignoreNull'='false')
from root.db.d1",
expectedHeader,
retArray);
// align by device
- expectedHeader = new String[] {"time", "device_id", "_col1", "_col2"};
+ expectedHeader =
+ new String[] {
+ TIMESTAMP_STR,
+ DEVICE,
+ "Diff(s1, \"ignoreNull\"=\"false\")",
+ "diff(s2, \"ignoreNull\"=\"false\")"
+ };
retArray =
new String[] {
- "1997-01-01T08:00:00.001Z,d1,null,null,",
- "1997-01-01T08:00:00.002Z,d1,1.0,null,",
- "1997-01-01T08:00:00.003Z,d1,null,null,",
- "1997-01-01T08:00:00.004Z,d1,null,null,",
- "1997-01-01T08:00:00.005Z,d1,1.0,null,",
- "1997-01-01T08:00:00.006Z,d1,null,1.0,",
- "1970-02-27T20:53:20.000Z,d1,null,1.0,",
- "1970-02-27T20:53:20.001Z,d1,null,null,",
- "1997-01-01T08:00:00.001Z,d2,null,null",
- "1997-01-01T08:00:00.002Z,d2,1.0,1.0,",
- "1970-02-27T20:53:20.000Z,d2,null,1.0,",
- "1970-02-27T20:53:20.001Z,d2,null,null,",
+ "1,root.db.d1,null,null,",
+ "2,root.db.d1,1.0,null,",
+ "3,root.db.d1,null,null,",
+ "4,root.db.d1,null,null,",
+ "5,root.db.d1,1.0,null,",
+ "6,root.db.d1,null,1.0,",
+ "5000000000,root.db.d1,null,1.0,",
+ "5000000001,root.db.d1,null,null,",
+ "1,root.db.d2,null,null,",
+ "2,root.db.d2,1.0,1.0,",
+ "5000000000,root.db.d2,null,1.0,",
+ "5000000001,root.db.d2,null,null,",
};
resultSetEqualTest(
- "select time, device_id, Diff(s1, false), diff(s2, false) from table1
where device_id='d1' or device_id='d2' order by device_id",
+ "select Diff(s1, 'ignoreNull'='false'), diff(s2, 'ignoreNull'='false')
from root.db.d1, root.db.d2 align by device",
expectedHeader,
retArray);
// align by device + order by time
retArray =
new String[] {
- "1997-01-01T08:00:00.001Z,d1,null,null,",
- "1997-01-01T08:00:00.001Z,d2,null,null",
- "1997-01-01T08:00:00.002Z,d1,1.0,null,",
- "1997-01-01T08:00:00.002Z,d2,1.0,1.0,",
- "1997-01-01T08:00:00.003Z,d1,null,null,",
- "1997-01-01T08:00:00.004Z,d1,null,null,",
- "1997-01-01T08:00:00.005Z,d1,1.0,null,",
- "1997-01-01T08:00:00.006Z,d1,null,1.0,",
- "1970-02-27T20:53:20.000Z,d1,null,1.0,",
- "1970-02-27T20:53:20.000Z,d2,null,1.0,",
- "1970-02-27T20:53:20.001Z,d1,null,null,",
- "1970-02-27T20:53:20.001Z,d2,null,null,",
+ "1,root.db.d1,null,null,",
+ "1,root.db.d2,null,null,",
+ "2,root.db.d1,1.0,null,",
+ "2,root.db.d2,1.0,1.0,",
+ "3,root.db.d1,null,null,",
+ "4,root.db.d1,null,null,",
+ "5,root.db.d1,1.0,null,",
+ "6,root.db.d1,null,1.0,",
+ "5000000000,root.db.d1,null,1.0,",
+ "5000000000,root.db.d2,null,1.0,",
+ "5000000001,root.db.d1,null,null,",
+ "5000000001,root.db.d2,null,null,",
};
resultSetEqualTest(
- "select time, device_id, Diff(s1, false), diff(s2, false) where
device_id='d1' or device_id='d2' order by time,device_id",
+ "select Diff(s1, 'ignoreNull'='false'), diff(s2, 'ignoreNull'='false')
from root.db.d1, root.db.d2 order by time align by device",
expectedHeader,
retArray);
}
+ // [change_points] is not mappable function, so this calculation use old
transformer
@Test
- public void testCaseInSensitive() {
- String[] expectedHeader = new String[] {"time", "s1", "s2"};
+ public void testOldTransformerIgnoreNull() {
+ String[] expectedHeader =
+ new String[] {TIMESTAMP_STR, "change_points(root.db.d1.s1)",
"diff(root.db.d1.s2)"};
+ String[] retArray =
+ new String[] {
+ "1,1,null,",
+ "2,2,null,",
+ "3,null,2.0,",
+ "4,4,null,",
+ "5,5,2.0,",
+ "6,null,1.0,",
+ "5000000000,null,1.0,",
+ "5000000001,8,null,"
+ };
+ resultSetEqualTest(
+ "select change_points(s1), diff(s2) from root.db.d1", expectedHeader,
retArray);
+
+ // align by device
+ expectedHeader = new String[] {TIMESTAMP_STR, DEVICE, "change_points(s1)",
"diff(s2)"};
+ retArray =
+ new String[] {
+ "1,root.db.d1,1,null,",
+ "2,root.db.d1,2,null,",
+ "3,root.db.d1,null,2.0,",
+ "4,root.db.d1,4,null,",
+ "5,root.db.d1,5,2.0,",
+ "6,root.db.d1,null,1.0,",
+ "5000000000,root.db.d1,null,1.0,",
+ "5000000001,root.db.d1,8,null,",
+ "1,root.db.d2,1,null,",
+ "2,root.db.d2,2,1.0,",
+ "5000000000,root.db.d2,null,1.0,",
+ "5000000001,root.db.d2,4,null,",
+ };
+ resultSetEqualTest(
+ "select change_points(s1), diff(s2) from root.db.d1, root.db.d2 align
by device",
+ expectedHeader,
+ retArray);
+
+ // align by device + order by time
+ expectedHeader = new String[] {TIMESTAMP_STR, DEVICE, "change_points(s1)",
"diff(s2)"};
+ retArray =
+ new String[] {
+ "1,root.db.d1,1,null,",
+ "1,root.db.d2,1,null,",
+ "2,root.db.d1,2,null,",
+ "2,root.db.d2,2,1.0,",
+ "3,root.db.d1,null,2.0,",
+ "4,root.db.d1,4,null,",
+ "5,root.db.d1,5,2.0,",
+ "6,root.db.d1,null,1.0,",
+ "5000000000,root.db.d1,null,1.0,",
+ "5000000000,root.db.d2,null,1.0,",
+ "5000000001,root.db.d1,8,null,",
+ "5000000001,root.db.d2,4,null,",
+ };
+ resultSetEqualTest(
+ "select change_points(s1), diff(s2) from root.db.d1, root.db.d2 order
by time align by device",
+ expectedHeader,
+ retArray);
+ }
+
+ @Test
+ public void testOldTransformerRespectNull() {
+ String[] expectedHeader =
+ new String[] {
+ TIMESTAMP_STR,
+ "change_points(root.db.d1.s1)",
+ "diff(root.db.d1.s2, \"ignoreNull\"=\"false\")"
+ };
String[] retArray =
new String[] {
- "1997-01-01T08:00:00.002Z,2,null,",
- "1997-01-01T08:00:00.004Z,4,null,",
- "1997-01-01T08:00:00.005Z,5,5.0,"
+ "1,1,null,",
+ "2,2,null,",
+ "4,4,null,",
+ "5,5,null,",
+ "6,null,1.0,",
+ "5000000000,null,1.0,",
+ "5000000001,8,null,"
+ };
+ resultSetEqualTest(
+ "select change_points(s1), diff(s2, 'ignoreNull'='false') from
root.db.d1",
+ expectedHeader,
+ retArray);
+
+ // align by device
+ expectedHeader =
+ new String[] {
+ TIMESTAMP_STR, DEVICE, "change_points(s1)", "diff(s2,
\"ignoreNull\"=\"false\")"
+ };
+ retArray =
+ new String[] {
+ "1,root.db.d1,1,null,",
+ "2,root.db.d1,2,null,",
+ "4,root.db.d1,4,null,",
+ "5,root.db.d1,5,null,",
+ "6,root.db.d1,null,1.0,",
+ "5000000000,root.db.d1,null,1.0,",
+ "5000000001,root.db.d1,8,null,",
+ "1,root.db.d2,1,null,",
+ "2,root.db.d2,2,1.0,",
+ "5000000000,root.db.d2,null,1.0,",
+ "5000000001,root.db.d2,4,null,",
+ };
+ resultSetEqualTest(
+ "select change_points(s1), diff(s2, 'ignoreNull'='false') from
root.db.d1, root.db.d2 align by device",
+ expectedHeader,
+ retArray);
+
+ // align by device + order by time
+ expectedHeader =
+ new String[] {
+ TIMESTAMP_STR, DEVICE, "change_points(s1)", "diff(s2,
\"ignoreNull\"=\"false\")"
};
+ retArray =
+ new String[] {
+ "1,root.db.d1,1,null,",
+ "1,root.db.d2,1,null,",
+ "2,root.db.d1,2,null,",
+ "2,root.db.d2,2,1.0,",
+ "4,root.db.d1,4,null,",
+ "5,root.db.d1,5,null,",
+ "6,root.db.d1,null,1.0,",
+ "5000000000,root.db.d1,null,1.0,",
+ "5000000000,root.db.d2,null,1.0,",
+ "5000000001,root.db.d1,8,null,",
+ "5000000001,root.db.d2,4,null,",
+ };
+ resultSetEqualTest(
+ "select change_points(s1), diff(s2, 'ignoreNull'='false') from
root.db.d1, root.db.d2 order by time align by device",
+ expectedHeader,
+ retArray);
+ }
+
+ @Test
+ public void testCaseInSensitive() {
+ String[] expectedHeader = new String[] {TIMESTAMP_STR, "root.db.d1.s1",
"root.db.d1.s2"};
+ String[] retArray = new String[] {"2,2,null,", "4,4,null,", "5,5,5.0,"};
+ resultSetEqualTest(
+ "select s1, s2 from root.db.d1 where Diff(s1) between 1 and 2",
expectedHeader, retArray);
+
+ retArray = new String[] {};
resultSetEqualTest(
- "select time, s1, s2 from table1 where device_id='d1' and diff(s1)
between 1 and 2",
+ "select s1, s2 from root.db.d1 where Diff(notExist) between 1 and 2",
expectedHeader,
retArray);
}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBDatetimeFormatIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBDatetimeFormatIT.java
new file mode 100644
index 00000000000..bf237caa66d
--- /dev/null
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBDatetimeFormatIT.java
@@ -0,0 +1,157 @@
+/*
+ * 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.relational.it.query.old;
+
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+import org.apache.iotdb.itbase.env.BaseEnv;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import static org.junit.Assert.fail;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({LocalStandaloneIT.class, ClusterIT.class})
+public class IoTDBDatetimeFormatIT {
+
+ private static final String DATABASE_NAME = "db";
+
+ @BeforeClass
+ public void setUp() throws Exception {
+
EnvFactory.getEnv().getConfig().getCommonConfig().setTimestampPrecisionCheckEnabled(false);
+ EnvFactory.getEnv().initClusterEnvironment();
+
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+ statement.execute("create database " + DATABASE_NAME);
+ statement.execute("use " + DATABASE_NAME);
+ statement.execute(
+ "create table table1(device_id STRING ID, s1 INT32 MEASUREMENT, s2
DOUBLE MEASUREMENT);");
+ }
+ }
+
+ @AfterClass
+ public void tearDown() throws Exception {
+ EnvFactory.getEnv().cleanClusterEnvironment();
+ }
+
+ @Test
+ public void testDatetimeInputFormat() {
+ String[] datetimeStrings = {
+ "2022-01-01 01:02:03", // yyyy-MM-dd HH:mm:ss
+ "2022/01/02 01:02:03", // yyyy/MM/dd HH:mm:ss
+ "2022.01.03 01:02:03", // yyyy.MM.dd HH:mm:ss
+ "2022-01-04 01:02:03+01:00", // yyyy-MM-dd HH:mm:ssZZ
+ "2022/01/05 01:02:03+01:00", // yyyy/MM/dd HH:mm:ssZZ
+ "2022.01.06 01:02:03+01:00", // yyyy.MM.dd HH:mm:ssZZ
+ "2022-01-07 01:02:03.400", // yyyy-MM-dd HH:mm:ss.SSS
+ "2022/01/08 01:02:03.400", // yyyy/MM/dd HH:mm:ss.SSS
+ "2022.01.09 01:02:03.400", // yyyy.MM.dd HH:mm:ss.SSS
+ "2022-01-10 01:02:03.400+01:00", // yyyy-MM-dd HH:mm:ss.SSSZZ
+ "2022-01-11 01:02:03.400+01:00", // yyyy/MM/dd HH:mm:ss.SSSZZ
+ "2022-01-12 01:02:03.400+01:00", // yyyy.MM.dd HH:mm:ss.SSSZZ
+ "2022-01-13T01:02:03.400+01:00" // ISO8601 standard time format
+ };
+ long[] timestamps = {
+ 1640970123000L,
+ 1641056523000L,
+ 1641142923000L,
+ 1641254523000L,
+ 1641340923000L,
+ 1641427323000L,
+ 1641488523400L,
+ 1641574923400L,
+ 1641661323400L,
+ 1641772923400L,
+ 1641859323400L,
+ 1641945723400L,
+ 1642032123400L
+ };
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+
+ connection.setClientInfo("time_zone", "+08:00");
+ statement.execute("use " + DATABASE_NAME);
+
+ for (int i = 0; i < datetimeStrings.length; i++) {
+ String insertSql =
+ String.format(
+ "INSERT INTO table1(time, device_id, s1) values (%s, %s, %d)",
+ datetimeStrings[i], "d1", i);
+ statement.execute(insertSql);
+ }
+
+ try (ResultSet resultSet =
+ statement.executeQuery("SELECT time, s1 FROM table1 where
device_id='d1'")) {
+ Assert.assertNotNull(resultSet);
+ int cnt = 0;
+ while (resultSet.next()) {
+ Assert.assertEquals(timestamps[cnt], resultSet.getLong(1));
+ cnt++;
+ }
+ Assert.assertEquals(timestamps.length, cnt);
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testBigDateTime() {
+
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+ statement.execute("use " + DATABASE_NAME);
+
+ statement.execute(
+ "insert into table1(time,device_id,s2) values (1618283005586000,
'd1',8.76);");
+
+ try (ResultSet resultSet =
+ statement.executeQuery(
+ "select time, s2 from table1 where device_id='d1' and
time=53251-05-07T17:06:26.000+08:00")) {
+ Assert.assertNotNull(resultSet);
+ int cnt = 0;
+ while (resultSet.next()) {
+ Assert.assertEquals(1618283005586000L, resultSet.getLong(1));
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBNestedQueryIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBNestedQueryIT.java
new file mode 100644
index 00000000000..629579747f0
--- /dev/null
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBNestedQueryIT.java
@@ -0,0 +1,460 @@
+/*
+ * 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.relational.it.query.old;
+
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+import org.apache.iotdb.itbase.env.BaseEnv;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({LocalStandaloneIT.class, ClusterIT.class})
+public class IoTDBNestedQueryIT {
+
+ private static final String DATABASE_NAME = "db";
+
+ protected static final int ITERATION_TIMES = 10;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ EnvFactory.getEnv()
+ .getConfig()
+ .getCommonConfig()
+ .setEnableSeqSpaceCompaction(false)
+ .setEnableUnseqSpaceCompaction(false)
+ .setEnableCrossSpaceCompaction(false)
+ .setUdfMemoryBudgetInMB(5);
+
+ EnvFactory.getEnv().initClusterEnvironment();
+ createTable();
+ generateData();
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ EnvFactory.getEnv().cleanClusterEnvironment();
+ }
+
+ private static void createTable() {
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+ statement.execute("CREATE DATABASE " + DATABASE_NAME);
+ statement.execute("USE " + DATABASE_NAME);
+ statement.execute(
+ "create table vehicle1(device_id STRING ID, s1 INT32 MEASUREMENT, s2
INT32 MEASUREMENT, s3 TEXT MEASUREMENT, s4 STRING MEASUREMENT, s5 DATE
MEASUREMENT, s6 TIMESTAMP MEASUREMENT);");
+
+ statement.execute(
+ "create table vehicle2(device_id STRING ID, s1 FLOAT MEASUREMENT, s2
DOUBLE MEASUREMENT, empty DOUBLE MEASUREMENT");
+ } catch (SQLException throwable) {
+ fail(throwable.getMessage());
+ }
+ }
+
+ private static void generateData() {
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+ statement.execute("USE " + DATABASE_NAME);
+ for (int i = 1; i <= ITERATION_TIMES; ++i) {
+ statement.execute(
+ String.format(
+ "insert into vehicle1(time,device_id,s1,s2,s3,s4,s6)
values(%d,%s%d,%d,%s,%s,%d)",
+ i, "d1", i, i, i, i, i));
+ statement.execute(
+ (String.format(
+ "insert into vehicle2(time,device_id,s1,s2)
values(%d,%s,%d,%d)", i, "d2", i, i)));
+ }
+ statement.execute("insert into vehicle1(timestamp,s5) values(1, 'd1',
'2024-01-01')");
+ statement.execute("insert into vehicle1(timestamp,s5) values(2,
'd1','2024-01-02')");
+ statement.execute("insert into vehicle1(timestamp,s5) values(3,
'd1','2024-01-03')");
+ } catch (SQLException throwable) {
+ fail(throwable.getMessage());
+ }
+ }
+
+ @Ignore
+ @Test
+ public void testNestedRowByRowUDFExpressions() {
+ String sqlStr =
+ "select time, s1, s2, sin(sin(s1) * sin(s2) + cos(s1) * cos(s1)) +
sin(sin(s1 - s1 + s2) * sin(s2) + cos(s1) * cos(s1)), asin(sin(asin(sin(s1 - s2
/ (-s1))))) from vehicle2";
+
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ ResultSet resultSet = statement.executeQuery(sqlStr);
+
+ assertEquals(1 + 4, resultSet.getMetaData().getColumnCount());
+
+ int count = 0;
+ while (resultSet.next()) {
+ ++count;
+
+ assertEquals(count, resultSet.getLong(1));
+ assertEquals(count, Double.parseDouble(resultSet.getString(2)), 0);
+ assertEquals(count, Double.parseDouble(resultSet.getString(3)), 0);
+ assertEquals(2 * Math.sin(1.0),
Double.parseDouble(resultSet.getString(4)), 1e-5);
+ assertEquals(
+ Math.asin(Math.sin(Math.asin(Math.sin(count - count / (-count))))),
+ Double.parseDouble(resultSet.getString(5)),
+ 1e-5);
+ }
+
+ assertEquals(ITERATION_TIMES, count);
+ } catch (SQLException throwable) {
+ fail(throwable.getMessage());
+ }
+ }
+
+ @Test
+ public void testRawDataQueryWithConstants() {
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+
+ String query = "SELECT time, 1 + s1 FROM vehicle1 where device_id='d1'";
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = 1; i <= ITERATION_TIMES; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(i, rs.getLong(1));
+ Assert.assertEquals(i + 1.0D, rs.getDouble(2), 0.01);
+ }
+ Assert.assertFalse(rs.next());
+ }
+
+ query = "SELECT time, (1 + 4) * 2 / 10 + s1 FROM vehicle1 where
device_id='d1'";
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = 1; i <= ITERATION_TIMES; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(i, rs.getLong(1));
+ Assert.assertEquals(i + 1.0D, rs.getDouble(2), 0.01);
+ }
+ Assert.assertFalse(rs.next());
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testDuplicatedRawDataQueryWithConstants() {
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+
+ String query = "SELECT time, 1 + s1, 1 + s1 FROM vehicle1 where
device_id='d1'";
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = 1; i <= ITERATION_TIMES; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(i, rs.getLong(1));
+ Assert.assertEquals(i + 1.0D, rs.getDouble(2), 0.01);
+ Assert.assertEquals(i + 1.0D, rs.getDouble(3), 0.01);
+ }
+ Assert.assertFalse(rs.next());
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testCommutativeLaws() {
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+
+ String query =
+ "SELECT time, s1, s1 + 1, 1 + s1, s1 * 2, 2 * s1 FROM vehicle1 where
device_id='d1'";
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = 1; i <= ITERATION_TIMES; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(i, rs.getLong(1));
+ Assert.assertEquals(i, rs.getInt(2));
+ Assert.assertEquals(i + 1.0D, rs.getDouble(3), 0.01);
+ Assert.assertEquals(i + 1.0D, rs.getDouble(4), 0.01);
+ Assert.assertEquals(i * 2.0D, rs.getDouble(5), 0.01);
+ Assert.assertEquals(i * 2.0D, rs.getDouble(6), 0.01);
+ }
+ Assert.assertFalse(rs.next());
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAssociativeLaws() {
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+
+ String query =
+ "SELECT time, s1, s1 + 1 + 2, (s1 + 1) + 2, s1 + (1 + 2), s1 * 2 *
3, s1 * (2 * 3), (s1 * 2) * 3 FROM vehicle1 where device_id='d1'";
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = 1; i <= ITERATION_TIMES; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(i, rs.getLong(1));
+ Assert.assertEquals(i, rs.getInt(2));
+ Assert.assertEquals(i + 3.0D, rs.getDouble(3), 0.01);
+ Assert.assertEquals(i + 3.0D, rs.getDouble(4), 0.01);
+ Assert.assertEquals(i + 3.0D, rs.getDouble(5), 0.01);
+ Assert.assertEquals(i * 6.0D, rs.getDouble(6), 0.01);
+ Assert.assertEquals(i * 6.0D, rs.getDouble(7), 0.01);
+ Assert.assertEquals(i * 6.0D, rs.getDouble(8), 0.01);
+ }
+ Assert.assertFalse(rs.next());
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testDistributiveLaw() {
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+
+ String query =
+ "SELECT time, s1, (s1 + 1) * 2, s1 * 2 + 1 * 2, (s1 + 1) / 2, s1 / 2
+ 1 / 2 FROM vehicle1 where device_id='d1'";
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = 1; i <= ITERATION_TIMES; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(i, rs.getLong(1));
+ Assert.assertEquals(i, rs.getInt(2));
+ Assert.assertEquals(2 * i + 2.0D, rs.getDouble(3), 0.01);
+ Assert.assertEquals(2 * i + 2.0D, rs.getDouble(4), 0.01);
+ Assert.assertEquals(i / 2.0D + 0.5D, rs.getDouble(5), 0.01);
+ Assert.assertEquals(i / 2.0D + 0.5D, rs.getDouble(6), 0.01);
+ }
+ Assert.assertFalse(rs.next());
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testOrderOfArithmeticOperations() {
+ // Priority from high to low:
+ // 1. exponentiation and root extraction (not supported yet)
+ // 2. multiplication and division
+ // 3. addition and subtraction
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+
+ String query =
+ "SELECT time, 1 + s1 * 2 + 1, (1 + s1) * 2 + 1, (1 + s1) * (2 + 1)
FROM vehicle1 where device_id='d1'";
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = 1; i <= ITERATION_TIMES; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(i, rs.getLong(1));
+ Assert.assertEquals(2 * i + 2.0D, rs.getDouble(2), 0.01);
+ Assert.assertEquals(2 * i + 3.0D, rs.getDouble(3), 0.01);
+ Assert.assertEquals(3 * i + 3.0D, rs.getDouble(4), 0.01);
+ }
+ Assert.assertFalse(rs.next());
+ }
+
+ query =
+ "SELECT time, 1 - s1 / 2 + 1, (1 - s1) / 2 + 1, (1 - s1) / (2 + 1)
FROM vehicle1 where device_id='d1'";
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = 1; i <= ITERATION_TIMES; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(i, rs.getLong(1));
+ Assert.assertEquals(2.0D - i / 2.0D, rs.getDouble(2), 0.01);
+ Assert.assertEquals(1.5 - i / 2.0D, rs.getDouble(3), 0.01);
+ Assert.assertEquals((1.0D / 3.0D) * (1.0D - i), rs.getDouble(4),
0.01);
+ }
+ Assert.assertFalse(rs.next());
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testBetweenExpression() {
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+ int start = 2, end = 8;
+ String query =
+ "SELECT * FROM vehicle1 where device_id='d1' WHERE s1 BETWEEN " +
start + " AND " + end;
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = start; i <= end; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(String.valueOf(i), rs.getString("time"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s1"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s2"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s3"));
+ }
+ }
+
+ query =
+ "SELECT * FROM vehicle1 where device_id='d1' WHERE s1 NOT BETWEEN "
// test not between
+ + (end + 1)
+ + " AND "
+ + ITERATION_TIMES;
+ try (ResultSet rs = statement.executeQuery(query)) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals("1", rs.getString("time"));
+ Assert.assertEquals("1", rs.getString("s1"));
+ Assert.assertEquals("1", rs.getString("s2"));
+ Assert.assertEquals("1", rs.getString("s3"));
+ for (int i = start; i <= end; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(String.valueOf(i), rs.getString("time"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s1"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s2"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s3"));
+ }
+ }
+
+ query =
+ "SELECT * FROM vehicle1 where device_id='d1' WHERE time BETWEEN " +
start + " AND " + end;
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = start; i <= end; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(String.valueOf(i), rs.getString("time"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s1"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s2"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s3"));
+ }
+ }
+
+ query =
+ "SELECT * FROM vehicle1 where device_id='d1' WHERE time NOT BETWEEN
" // test not between
+ + (end + 1)
+ + " AND "
+ + ITERATION_TIMES;
+ try (ResultSet rs = statement.executeQuery(query)) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals("1", rs.getString("time"));
+ Assert.assertEquals("1", rs.getString("s1"));
+ Assert.assertEquals("1", rs.getString("s2"));
+ Assert.assertEquals("1", rs.getString("s3"));
+ for (int i = start; i <= end; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(String.valueOf(i), rs.getString("time"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s1"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s2"));
+ Assert.assertEquals(String.valueOf(i), rs.getString("s3"));
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testRegularLikeInExpressions() {
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+ // String query =
+ // "SELECT s1 FROM vehicle1 where device_id='d1' WHERE s3 LIKE
'_' && s3 REGEXP
+ // '[0-9]' && s3 IN ('4', '2', '3')";
+ // try (ResultSet rs = statement.executeQuery(query)) {
+ // for (int i = 2; i <= 4; i++) {
+ // Assert.assertTrue(rs.next());
+ // Assert.assertEquals(i, rs.getLong(1));
+ // }
+ // Assert.assertFalse(rs.next());
+ // }
+
+ // String query2 =
+ // "SELECT s1 FROM vehicle1 where device_id='d1' WHERE s4 LIKE
'_' && s4 REGEXP
+ // '[0-9]' && s4 IN ('4', '2', '3')";
+ // try (ResultSet rs = statement.executeQuery(query2)) {
+ // for (int i = 2; i <= 4; i++) {
+ // Assert.assertTrue(rs.next());
+ // Assert.assertEquals(i, rs.getLong(1));
+ // }
+ // Assert.assertFalse(rs.next());
+ // }
+
+ String query3 =
+ "SELECT time,s1 FROM vehicle1 where device_id='d1' WHERE s5 IN
('2024-01-01', '2024-01-02', '2024-01-03')";
+ try (ResultSet rs = statement.executeQuery(query3)) {
+ for (int i = 1; i <= 3; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(i, rs.getLong(1));
+ }
+ Assert.assertFalse(rs.next());
+ }
+
+ String query4 = "SELECT time,s1 FROM vehicle1 where device_id='d1' WHERE
s6 IN (1, 2, 3)";
+ try (ResultSet rs = statement.executeQuery(query4)) {
+ for (int i = 1; i <= 3; i++) {
+ Assert.assertTrue(rs.next());
+ Assert.assertEquals(i, rs.getLong(1));
+ }
+ Assert.assertFalse(rs.next());
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testTimeExpressions() {
+ try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ Statement statement = connection.createStatement()) {
+ String query =
+ "SELECT s1, time, time, -(-time), time + 1 - 1, time + s1 - s1, time
+ 1 - 1 FROM vehicle1 where device_id='d1'";
+ try (ResultSet rs = statement.executeQuery(query)) {
+ for (int i = 1; i <= ITERATION_TIMES; ++i) {
+ assertTrue(rs.next());
+ for (int j = 1; j <= 7; ++j) {
+ assertEquals(i, Double.parseDouble(rs.getString(j)), 0.001);
+ }
+ }
+ assertFalse(rs.next());
+ }
+
+ query = "SELECT time, 2 * time FROM vehicle1 where device_id='d1'";
+ try (ResultSet rs = statement.executeQuery(query)) {
+ assertFalse(rs.next());
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBDiffFunctionIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBDiffFunctionIT.java
index 9da3963c5da..4cc357351aa 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBDiffFunctionIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBDiffFunctionIT.java
@@ -35,31 +35,31 @@ import java.sql.Connection;
import java.sql.Statement;
import static org.apache.iotdb.db.it.utils.TestUtils.resultSetEqualTest;
-import static org.apache.iotdb.itbase.constant.TestConstant.DEVICE;
-import static org.apache.iotdb.itbase.constant.TestConstant.TIMESTAMP_STR;
@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class, ClusterIT.class})
public class IoTDBDiffFunctionIT {
+
+ private static final String DATABASE_NAME = "db";
+
+ // 2 devices 4 regions
protected static final String[] SQLs =
new String[] {
- "CREATE DATABASE root.db",
- "CREATE TIMESERIES root.db.d1.s1 WITH DATATYPE=INT32, ENCODING=PLAIN",
- "CREATE TIMESERIES root.db.d1.s2 WITH DATATYPE=FLOAT, ENCODING=PLAIN",
- "INSERT INTO root.db.d1(timestamp,s1,s2) values(1, 1, 1)",
- "INSERT INTO root.db.d1(timestamp,s1) values(2, 2)",
- "INSERT INTO root.db.d1(timestamp,s2) values(3, 3)",
- "INSERT INTO root.db.d1(timestamp,s1) values(4, 4)",
- "INSERT INTO root.db.d1(timestamp,s1,s2) values(5, 5, 5)",
- "INSERT INTO root.db.d1(timestamp,s2) values(6, 6)",
- "INSERT INTO root.db.d1(timestamp,s1,s2) values(5000000000, null, 7)",
- "INSERT INTO root.db.d1(timestamp,s1,s2) values(5000000001, 8, null)",
- "CREATE TIMESERIES root.db.d2.s1 WITH DATATYPE=INT32, ENCODING=PLAIN",
- "CREATE TIMESERIES root.db.d2.s2 WITH DATATYPE=FLOAT, ENCODING=PLAIN",
- "INSERT INTO root.db.d2(timestamp,s1,s2) values(1, 1, 1)",
- "INSERT INTO root.db.d2(timestamp,s1,s2) values(2, 2, 2)",
- "INSERT INTO root.db.d2(timestamp,s1,s2) values(5000000000, null, 3)",
- "INSERT INTO root.db.d2(timestamp,s1,s2) values(5000000001, 4, null)",
+ "CREATE DATABASE " + DATABASE_NAME,
+ "use " + DATABASE_NAME,
+ "create table table1(device_id STRING ID, s1 INT32 MEASUREMENT, s2
INT32 MEASUREMENT);",
+ "INSERT INTO table1(time,device_id,s1,s2) values(1, 'd1', 1, 1)",
+ "INSERT INTO table1(time,device_id,s1) values(2, 'd1', 2)",
+ "INSERT INTO table1(time,device_id,s2) values(3, 'd1', 3)",
+ "INSERT INTO table1(time,device_id,s1) values(4, 'd1', 4)",
+ "INSERT INTO table1(time,device_id,s1,s2) values(5, 'd1', 5, 5)",
+ "INSERT INTO table1(time,device_id,s2) values(6, 'd1', 6)",
+ "INSERT INTO table1(time,device_id,s1,s2) values(5000000000, 'd1',
null, 7)",
+ "INSERT INTO table1(time,device_id,s1,s2) values(5000000001, 'd1', 8,
null)",
+ "INSERT INTO table1(time,device_id,s1,s2) values(1, 'd2', 1, 1)",
+ "INSERT INTO table1(time,device_id,s1,s2) values(2, 'd2', 2, 2)",
+ "INSERT INTO table1(time,device_id,s1,s2) values(5000000000, 'd2',
null, 3)",
+ "INSERT INTO table1(time,device_id,s1,s2) values(5000000001, 'd2', 4,
null)",
"flush"
};
@@ -89,285 +89,141 @@ public class IoTDBDiffFunctionIT {
@Test
public void testNewTransformerIgnoreNull() {
- String[] expectedHeader =
- new String[] {TIMESTAMP_STR, "Diff(root.db.d1.s1)",
"diff(root.db.d1.s2)"};
- String[] retArray =
- new String[] {
- "1,null,null,",
- "2,1.0,null,",
- "3,null,2.0,",
- "4,2.0,null,",
- "5,1.0,2.0,",
- "6,null,1.0,",
- "5000000000,null,1.0,",
- "5000000001,3.0,null,"
- };
- resultSetEqualTest("select Diff(s1), diff(s2) from root.db.d1",
expectedHeader, retArray);
-
- // align by device
- expectedHeader = new String[] {TIMESTAMP_STR, DEVICE, "Diff(s1)",
"diff(s2)"};
- retArray =
- new String[] {
- "1,root.db.d1,null,null,",
- "2,root.db.d1,1.0,null,",
- "3,root.db.d1,null,2.0,",
- "4,root.db.d1,2.0,null,",
- "5,root.db.d1,1.0,2.0,",
- "6,root.db.d1,null,1.0,",
- "5000000000,root.db.d1,null,1.0,",
- "5000000001,root.db.d1,3.0,null,",
- "1,root.db.d2,null,null,",
- "2,root.db.d2,1.0,1.0,",
- "5000000000,root.db.d2,null,1.0,",
- "5000000001,root.db.d2,2.0,null,"
- };
- resultSetEqualTest(
- "select Diff(s1), diff(s2) from root.db.d1, root.db.d2 align by
device",
- expectedHeader,
- retArray);
-
- // align by device + order by time
- retArray =
- new String[] {
- "1,root.db.d1,null,null,",
- "1,root.db.d2,null,null,",
- "2,root.db.d1,1.0,null,",
- "2,root.db.d2,1.0,1.0,",
- "3,root.db.d1,null,2.0,",
- "4,root.db.d1,2.0,null,",
- "5,root.db.d1,1.0,2.0,",
- "6,root.db.d1,null,1.0,",
- "5000000000,root.db.d1,null,1.0,",
- "5000000000,root.db.d2,null,1.0,",
- "5000000001,root.db.d1,3.0,null,",
- "5000000001,root.db.d2,2.0,null,"
- };
- resultSetEqualTest(
- "select Diff(s1), diff(s2) from root.db.d1, root.db.d2 order by time
align by device",
- expectedHeader,
- retArray);
- }
-
- @Test
- public void testNewTransformerRespectNull() {
- String[] expectedHeader =
- new String[] {
- TIMESTAMP_STR,
- "Diff(root.db.d1.s1, \"ignoreNull\"=\"false\")",
- "diff(root.db.d1.s2, \"ignoreNull\"=\"false\")"
- };
+ String[] expectedHeader = new String[] {"time", "_col1", "_col2"};
String[] retArray =
new String[] {
- "1,null,null,",
- "2,1.0,null,",
- "3,null,null,",
- "4,null,null,",
- "5,1.0,null,",
- "6,null,1.0,",
- "5000000000,null,1.0,",
- "5000000001,null,null,"
- };
- resultSetEqualTest(
- "select Diff(s1, 'ignoreNull'='false'), diff(s2, 'ignoreNull'='false')
from root.db.d1",
- expectedHeader,
- retArray);
-
- // align by device
- expectedHeader =
- new String[] {
- TIMESTAMP_STR,
- DEVICE,
- "Diff(s1, \"ignoreNull\"=\"false\")",
- "diff(s2, \"ignoreNull\"=\"false\")"
- };
- retArray =
- new String[] {
- "1,root.db.d1,null,null,",
- "2,root.db.d1,1.0,null,",
- "3,root.db.d1,null,null,",
- "4,root.db.d1,null,null,",
- "5,root.db.d1,1.0,null,",
- "6,root.db.d1,null,1.0,",
- "5000000000,root.db.d1,null,1.0,",
- "5000000001,root.db.d1,null,null,",
- "1,root.db.d2,null,null,",
- "2,root.db.d2,1.0,1.0,",
- "5000000000,root.db.d2,null,1.0,",
- "5000000001,root.db.d2,null,null,",
- };
- resultSetEqualTest(
- "select Diff(s1, 'ignoreNull'='false'), diff(s2, 'ignoreNull'='false')
from root.db.d1, root.db.d2 align by device",
- expectedHeader,
- retArray);
-
- // align by device + order by time
- retArray =
- new String[] {
- "1,root.db.d1,null,null,",
- "1,root.db.d2,null,null,",
- "2,root.db.d1,1.0,null,",
- "2,root.db.d2,1.0,1.0,",
- "3,root.db.d1,null,null,",
- "4,root.db.d1,null,null,",
- "5,root.db.d1,1.0,null,",
- "6,root.db.d1,null,1.0,",
- "5000000000,root.db.d1,null,1.0,",
- "5000000000,root.db.d2,null,1.0,",
- "5000000001,root.db.d1,null,null,",
- "5000000001,root.db.d2,null,null,",
+ "1997-01-01T08:00:00.001Z,null,null,",
+ "1997-01-01T08:00:00.002Z,1.0,null,",
+ "1997-01-01T08:00:00.003Z,null,2.0,",
+ "1997-01-01T08:00:00.004Z,2.0,null,",
+ "1997-01-01T08:00:00.005Z,1.0,2.0,",
+ "1997-01-01T08:00:00.006Z,null,1.0,",
+ "1970-02-27T20:53:20.000Z,null,1.0,",
+ "1970-02-27T20:53:20.001Z,3.0,null,"
};
resultSetEqualTest(
- "select Diff(s1, 'ignoreNull'='false'), diff(s2, 'ignoreNull'='false')
from root.db.d1, root.db.d2 order by time align by device",
+ "select time,diff(s1), diff(s2) from table1 where device_id='d1'",
expectedHeader,
retArray);
- }
-
- // [change_points] is not mappable function, so this calculation use old
transformer
- @Test
- public void testOldTransformerIgnoreNull() {
- String[] expectedHeader =
- new String[] {TIMESTAMP_STR, "change_points(root.db.d1.s1)",
"diff(root.db.d1.s2)"};
- String[] retArray =
- new String[] {
- "1,1,null,",
- "2,2,null,",
- "3,null,2.0,",
- "4,4,null,",
- "5,5,2.0,",
- "6,null,1.0,",
- "5000000000,null,1.0,",
- "5000000001,8,null,"
- };
- resultSetEqualTest(
- "select change_points(s1), diff(s2) from root.db.d1", expectedHeader,
retArray);
// align by device
- expectedHeader = new String[] {TIMESTAMP_STR, DEVICE, "change_points(s1)",
"diff(s2)"};
+ expectedHeader = new String[] {"time", "device_id", "_col1", "_col2"};
retArray =
new String[] {
- "1,root.db.d1,1,null,",
- "2,root.db.d1,2,null,",
- "3,root.db.d1,null,2.0,",
- "4,root.db.d1,4,null,",
- "5,root.db.d1,5,2.0,",
- "6,root.db.d1,null,1.0,",
- "5000000000,root.db.d1,null,1.0,",
- "5000000001,root.db.d1,8,null,",
- "1,root.db.d2,1,null,",
- "2,root.db.d2,2,1.0,",
- "5000000000,root.db.d2,null,1.0,",
- "5000000001,root.db.d2,4,null,",
+ "1997-01-01T08:00:00.001Z,d1,null,null,",
+ "1997-01-01T08:00:00.002Z,d1,1.0,null,",
+ "1997-01-01T08:00:00.003Z,d1,null,2.0,",
+ "1997-01-01T08:00:00.004Z,d1,2.0,null,",
+ "1997-01-01T08:00:00.005Z,d1,1.0,2.0,",
+ "1997-01-01T08:00:00.006Z,d1,null,1.0,",
+ "1970-02-27T20:53:20.000Z,d1,null,1.0,",
+ "1970-02-27T20:53:20.001Z,d1,3.0,null,",
+ "1997-01-01T08:00:00.001Z,d2,-7.0,-6.0",
+ "1997-01-01T08:00:00.002Z,d2,1.0,1.0,",
+ "1970-02-27T20:53:20.000Z,d2,null,1.0,",
+ "1970-02-27T20:53:20.001Z,d2,2.0,null,",
};
resultSetEqualTest(
- "select change_points(s1), diff(s2) from root.db.d1, root.db.d2 align
by device",
+ "select time, device_id, Diff(s1), diff(s2) from table1 where
device_id='d1' or device_id='d2' order by device_id",
expectedHeader,
retArray);
// align by device + order by time
- expectedHeader = new String[] {TIMESTAMP_STR, DEVICE, "change_points(s1)",
"diff(s2)"};
retArray =
new String[] {
- "1,root.db.d1,1,null,",
- "1,root.db.d2,1,null,",
- "2,root.db.d1,2,null,",
- "2,root.db.d2,2,1.0,",
- "3,root.db.d1,null,2.0,",
- "4,root.db.d1,4,null,",
- "5,root.db.d1,5,2.0,",
- "6,root.db.d1,null,1.0,",
- "5000000000,root.db.d1,null,1.0,",
- "5000000000,root.db.d2,null,1.0,",
- "5000000001,root.db.d1,8,null,",
- "5000000001,root.db.d2,4,null,",
+ "1997-01-01T08:00:00.001Z,d1,null,null,",
+ "1997-01-01T08:00:00.001Z,d2,null,null",
+ "1997-01-01T08:00:00.002Z,d1,1.0,null,",
+ "1997-01-01T08:00:00.002Z,d2,1.0,1.0,",
+ "1997-01-01T08:00:00.003Z,d1,null,2.0,",
+ "1997-01-01T08:00:00.004Z,d1,2.0,null,",
+ "1997-01-01T08:00:00.005Z,d1,1.0,2.0,",
+ "1997-01-01T08:00:00.006Z,d1,null,1.0,",
+ "1970-02-27T20:53:20.000Z,d1,null,1.0,",
+ "1970-02-27T20:53:20.000Z,d2,null,1.0,",
+ "1970-02-27T20:53:20.001Z,d1,3.0,null,",
+ "1970-02-27T20:53:20.001Z,d2,2.0,null,",
};
resultSetEqualTest(
- "select change_points(s1), diff(s2) from root.db.d1, root.db.d2 order
by time align by device",
+ "select time, device_id, Diff(s1), diff(s2) from table1 where
device_id='d1' or device_id='d2' order by time,device_id",
expectedHeader,
retArray);
}
@Test
- public void testOldTransformerRespectNull() {
- String[] expectedHeader =
- new String[] {
- TIMESTAMP_STR,
- "change_points(root.db.d1.s1)",
- "diff(root.db.d1.s2, \"ignoreNull\"=\"false\")"
- };
+ public void testNewTransformerRespectNull() {
+ String[] expectedHeader = new String[] {"time", "_col1", "_col2"};
String[] retArray =
new String[] {
- "1,1,null,",
- "2,2,null,",
- "4,4,null,",
- "5,5,null,",
- "6,null,1.0,",
- "5000000000,null,1.0,",
- "5000000001,8,null,"
+ "1997-01-01T08:00:00.001Z,null,null,",
+ "1997-01-01T08:00:00.002Z,1.0,null,",
+ "1997-01-01T08:00:00.003Z,null,null,",
+ "1997-01-01T08:00:00.004Z,null,null,",
+ "1997-01-01T08:00:00.005Z,1.0,null,",
+ "1997-01-01T08:00:00.006Z,null,1.0,",
+ "1970-02-27T20:53:20.000Z,null,1.0,",
+ "1970-02-27T20:53:20.001Z,null,null,"
};
resultSetEqualTest(
- "select change_points(s1), diff(s2, 'ignoreNull'='false') from
root.db.d1",
+ "select time, Diff(s1, false), diff(s2, false) from table1 where
device_id='d1'",
expectedHeader,
retArray);
// align by device
- expectedHeader =
- new String[] {
- TIMESTAMP_STR, DEVICE, "change_points(s1)", "diff(s2,
\"ignoreNull\"=\"false\")"
- };
+ expectedHeader = new String[] {"time", "device_id", "_col1", "_col2"};
retArray =
new String[] {
- "1,root.db.d1,1,null,",
- "2,root.db.d1,2,null,",
- "4,root.db.d1,4,null,",
- "5,root.db.d1,5,null,",
- "6,root.db.d1,null,1.0,",
- "5000000000,root.db.d1,null,1.0,",
- "5000000001,root.db.d1,8,null,",
- "1,root.db.d2,1,null,",
- "2,root.db.d2,2,1.0,",
- "5000000000,root.db.d2,null,1.0,",
- "5000000001,root.db.d2,4,null,",
+ "1997-01-01T08:00:00.001Z,d1,null,null,",
+ "1997-01-01T08:00:00.002Z,d1,1.0,null,",
+ "1997-01-01T08:00:00.003Z,d1,null,null,",
+ "1997-01-01T08:00:00.004Z,d1,null,null,",
+ "1997-01-01T08:00:00.005Z,d1,1.0,null,",
+ "1997-01-01T08:00:00.006Z,d1,null,1.0,",
+ "1970-02-27T20:53:20.000Z,d1,null,1.0,",
+ "1970-02-27T20:53:20.001Z,d1,null,null,",
+ "1997-01-01T08:00:00.001Z,d2,null,null",
+ "1997-01-01T08:00:00.002Z,d2,1.0,1.0,",
+ "1970-02-27T20:53:20.000Z,d2,null,1.0,",
+ "1970-02-27T20:53:20.001Z,d2,null,null,",
};
resultSetEqualTest(
- "select change_points(s1), diff(s2, 'ignoreNull'='false') from
root.db.d1, root.db.d2 align by device",
+ "select time, device_id, Diff(s1, false), diff(s2, false) from table1
where device_id='d1' or device_id='d2' order by device_id",
expectedHeader,
retArray);
// align by device + order by time
- expectedHeader =
- new String[] {
- TIMESTAMP_STR, DEVICE, "change_points(s1)", "diff(s2,
\"ignoreNull\"=\"false\")"
- };
retArray =
new String[] {
- "1,root.db.d1,1,null,",
- "1,root.db.d2,1,null,",
- "2,root.db.d1,2,null,",
- "2,root.db.d2,2,1.0,",
- "4,root.db.d1,4,null,",
- "5,root.db.d1,5,null,",
- "6,root.db.d1,null,1.0,",
- "5000000000,root.db.d1,null,1.0,",
- "5000000000,root.db.d2,null,1.0,",
- "5000000001,root.db.d1,8,null,",
- "5000000001,root.db.d2,4,null,",
+ "1997-01-01T08:00:00.001Z,d1,null,null,",
+ "1997-01-01T08:00:00.001Z,d2,null,null",
+ "1997-01-01T08:00:00.002Z,d1,1.0,null,",
+ "1997-01-01T08:00:00.002Z,d2,1.0,1.0,",
+ "1997-01-01T08:00:00.003Z,d1,null,null,",
+ "1997-01-01T08:00:00.004Z,d1,null,null,",
+ "1997-01-01T08:00:00.005Z,d1,1.0,null,",
+ "1997-01-01T08:00:00.006Z,d1,null,1.0,",
+ "1970-02-27T20:53:20.000Z,d1,null,1.0,",
+ "1970-02-27T20:53:20.000Z,d2,null,1.0,",
+ "1970-02-27T20:53:20.001Z,d1,null,null,",
+ "1970-02-27T20:53:20.001Z,d2,null,null,",
};
resultSetEqualTest(
- "select change_points(s1), diff(s2, 'ignoreNull'='false') from
root.db.d1, root.db.d2 order by time align by device",
+ "select time, device_id, Diff(s1, false), diff(s2, false) where
device_id='d1' or device_id='d2' order by time,device_id",
expectedHeader,
retArray);
}
@Test
public void testCaseInSensitive() {
- String[] expectedHeader = new String[] {TIMESTAMP_STR, "root.db.d1.s1",
"root.db.d1.s2"};
- String[] retArray = new String[] {"2,2,null,", "4,4,null,", "5,5,5.0,"};
- resultSetEqualTest(
- "select s1, s2 from root.db.d1 where Diff(s1) between 1 and 2",
expectedHeader, retArray);
-
- retArray = new String[] {};
+ String[] expectedHeader = new String[] {"time", "s1", "s2"};
+ String[] retArray =
+ new String[] {
+ "1997-01-01T08:00:00.002Z,2,null,",
+ "1997-01-01T08:00:00.004Z,4,null,",
+ "1997-01-01T08:00:00.005Z,5,5.0,"
+ };
resultSetEqualTest(
- "select s1, s2 from root.db.d1 where Diff(notExist) between 1 and 2",
+ "select time, s1, s2 from table1 where device_id='d1' and diff(s1)
between 1 and 2",
expectedHeader,
retArray);
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analyzer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analyzer.java
index 88f235902e0..421fc8eaebf 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analyzer.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analyzer.java
@@ -19,6 +19,7 @@
package org.apache.iotdb.db.queryengine.plan.relational.analyzer;
+import org.apache.iotdb.db.exception.sql.SemanticException;
import org.apache.iotdb.db.queryengine.common.SessionInfo;
import org.apache.iotdb.db.queryengine.execution.warnings.WarningCollector;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
@@ -57,6 +58,9 @@ public class Analyzer {
public Analysis analyze(Statement statement) {
Analysis analysis = new Analysis(statement, parameterLookup);
+ if (!session.getDatabaseName().isPresent()) {
+ throw new SemanticException("database is not specified");
+ }
analysis.setDatabaseName(session.getDatabaseName().get());
StatementAnalyzer analyzer =
statementAnalyzerFactory.createStatementAnalyzer(
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertPredicateToFilterVisitor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertPredicateToFilterVisitor.java
index 3c520aae3f7..80fcf5bce87 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertPredicateToFilterVisitor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertPredicateToFilterVisitor.java
@@ -36,6 +36,7 @@ import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IsNullPredicate;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LikePredicate;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LogicalExpression;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.NotExpression;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.NullIfExpression;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SearchedCaseExpression;
@@ -326,7 +327,13 @@ public class ConvertPredicateToFilterVisitor
}
public static double getDoubleValue(Expression expression) {
- return ((DoubleLiteral) expression).getValue();
+ if (expression instanceof DoubleLiteral) {
+ return ((DoubleLiteral) expression).getValue();
+ } else if (expression instanceof LongLiteral) {
+ return ((LongLiteral) expression).getParsedValue();
+ } else {
+ throw new IllegalArgumentException("expression should be numeric, actual
is " + expression);
+ }
}
public static boolean getBooleanValue(Expression expression) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/NormalizeOrExpressionRewriter.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/NormalizeOrExpressionRewriter.java
index 8653d92aff2..3823406d1c3 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/NormalizeOrExpressionRewriter.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/NormalizeOrExpressionRewriter.java
@@ -21,6 +21,7 @@ package
org.apache.iotdb.db.queryengine.plan.relational.planner.ir;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ComparisonExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
+import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.InListExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.InPredicate;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LogicalExpression;
@@ -68,9 +69,8 @@ public final class NormalizeOrExpressionRewriter {
.forEach(
(expression, values) -> {
if (values.size() > 1) {
- // TODO mergeToInListExpression may have more than one value
inPredicateBuilder.add(
- new InPredicate(expression,
mergeToInListExpression(values).get(0)));
+ new InPredicate(expression,
mergeToInListExpression(values)));
expressionToSkipBuilder.add(expression);
}
});
@@ -99,21 +99,22 @@ public final class NormalizeOrExpressionRewriter {
.build());
}
- private List<Expression> mergeToInListExpression(Collection<Expression>
expressions) {
+ private InListExpression mergeToInListExpression(Collection<Expression>
expressions) {
LinkedHashSet<Expression> expressionValues = new LinkedHashSet<>();
for (Expression expression : expressions) {
if (expression instanceof ComparisonExpression
&& ((ComparisonExpression) expression).getOperator() == EQUAL) {
expressionValues.add(((ComparisonExpression) expression).getRight());
- } else if (expression instanceof InPredicate) {
- // TODO inPredicate has getValues method
- expressionValues.add(((InPredicate) expression).getValue());
+ } else if (expression instanceof InPredicate
+ && ((InPredicate) expression).getValueList() instanceof
InListExpression) {
+ expressionValues.addAll(
+ ((InListExpression) ((InPredicate)
expression).getValueList()).getValues());
} else {
throw new IllegalStateException("Unexpected expression: " +
expression);
}
}
- return ImmutableList.copyOf(expressionValues);
+ return new InListExpression(ImmutableList.copyOf(expressionValues));
}
private Map<Expression, Collection<Expression>>
groupComparisonAndInPredicate(
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
index ae9b8bf1d7a..49834085b97 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
@@ -1385,6 +1385,14 @@ public class AstBuilder extends
RelationalSqlBaseVisitor<Node> {
return new CurrentTime(getLocation(ctx), function);
}
+ @Override
+ public Node
visitDateTimeExpression(RelationalSqlParser.DateTimeExpressionContext ctx) {
+ return new LongLiteral(
+ getLocation(ctx),
+ String.valueOf(
+ parseDateExpression(ctx.dateExpression(),
CommonDateTimeUtils.currentTime())));
+ }
+
@Override
public Node visitTrim(RelationalSqlParser.TrimContext ctx) {
if (ctx.FROM() != null && ctx.trimsSpecification() == null && ctx.trimChar
== null) {
@@ -1589,6 +1597,15 @@ public class AstBuilder extends
RelationalSqlBaseVisitor<Node> {
return new BooleanLiteral(getLocation(ctx), ctx.getText());
}
+ @Override
+ public Node visitDatetimeLiteral(RelationalSqlParser.DatetimeLiteralContext
ctx) {
+ return new LongLiteral(
+ getLocation(ctx),
+ String.valueOf(
+ parseDateTimeFormat(
+ ctx.getChild(0).getText(), CommonDateTimeUtils.currentTime(),
zoneId)));
+ }
+
@Override
public Node visitParameter(RelationalSqlParser.ParameterContext ctx) {
Parameter parameter = new Parameter(getLocation(ctx), parameterPosition);
diff --git
a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
index 05d2a881735..a10ea67456a 100644
---
a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
+++
b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
@@ -442,10 +442,10 @@ timeValue
;
dateExpression
- : datetimeLiteral ((PLUS | MINUS) timeDuration)*
+ : datetime ((PLUS | MINUS) timeDuration)*
;
-datetimeLiteral
+datetime
: DATETIME_VALUE
| NOW '(' ')'
;
@@ -543,6 +543,7 @@ valueExpression
primaryExpression
: literalExpression
#literal
+ | dateExpression
#dateTimeExpression
| '(' expression (',' expression)+ ')'
#rowConstructor
| ROW '(' expression (',' expression)* ')'
#rowConstructor
| qualifiedName '(' (label=identifier '.')? ASTERISK ')'
#functionCall
@@ -570,6 +571,7 @@ literalExpression
| number
#numericLiteral
| booleanValue
#booleanLiteral
| string
#stringLiteral
+ | datetime
#datetimeLiteral
| BINARY_LITERAL
#binaryLiteral
| QUESTION_MARK
#parameter
;