This is an automated email from the ASF dual-hosted git repository.
jackietien 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 aa15d1a540 [IOTDB-3501] Add IT for syntax convention in new cluster
(#6456)
aa15d1a540 is described below
commit aa15d1a540d0b966d65c1b5172ed8bdf3d462da8
Author: Liao Lanyu <[email protected]>
AuthorDate: Tue Jun 28 12:10:33 2022 +0800
[IOTDB-3501] Add IT for syntax convention in new cluster (#6456)
---
.../apache/iotdb/itbase/constant/TestConstant.java | 1 +
.../db/it/IoTDBSyntaxConventionIdentifierIT.java | 998 +++++++++++++++++++++
.../it/IoTDBSyntaxConventionStringLiteralIT.java | 705 +++++++++++++++
3 files changed, 1704 insertions(+)
diff --git
a/integration-test/src/main/java/org/apache/iotdb/itbase/constant/TestConstant.java
b/integration-test/src/main/java/org/apache/iotdb/itbase/constant/TestConstant.java
index 29361299ad..08b1415280 100644
---
a/integration-test/src/main/java/org/apache/iotdb/itbase/constant/TestConstant.java
+++
b/integration-test/src/main/java/org/apache/iotdb/itbase/constant/TestConstant.java
@@ -50,6 +50,7 @@ public class TestConstant {
public static final String TIMESEIRES_STR = "timeseries";
public static final String VALUE_STR = "value";
public static final String DATA_TYPE_STR = "dataType";
+ public static final String FUNCTION_TYPE_NATIVE = "native";
public static String[] createSql =
new String[] {
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSyntaxConventionIdentifierIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSyntaxConventionIdentifierIT.java
new file mode 100644
index 0000000000..c57b77ef95
--- /dev/null
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSyntaxConventionIdentifierIT.java
@@ -0,0 +1,998 @@
+/*
+ * 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.it;
+
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.env.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+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 java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.fail;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({LocalStandaloneIT.class, ClusterIT.class})
+public class IoTDBSyntaxConventionIdentifierIT {
+ @Before
+ public void setUp() throws Exception {
+ EnvFactory.getEnv().initBeforeTest();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ EnvFactory.getEnv().cleanAfterTest();
+ }
+
+ @Test
+ public void testKeyWord() {
+ String[] createNodeNames = {
+ "add",
+ "as",
+ "between",
+ "select",
+ "drop_trigger",
+ "REVOKE_USER_ROLE",
+ "pipesink",
+ "boolean",
+ "datatype",
+ "device",
+ };
+
+ String[] resultTimeseries = {
+ "root.sg1.d1.add",
+ "root.sg1.d1.as",
+ "root.sg1.d1.between",
+ "root.sg1.d1.select",
+ "root.sg1.d1.drop_trigger",
+ "root.sg1.d1.REVOKE_USER_ROLE",
+ "root.sg1.d1.pipesink",
+ "root.sg1.d1.boolean",
+ "root.sg1.d1.datatype",
+ "root.sg1.d1.device",
+ };
+
+ String[] selectNodeNames = {
+ "add",
+ "as",
+ "between",
+ "select",
+ "drop_trigger",
+ "REVOKE_USER_ROLE",
+ "pipesink",
+ "boolean",
+ "datatype",
+ "device",
+ };
+
+ String[] suffixInResultColumns = {
+ "add",
+ "as",
+ "between",
+ "select",
+ "drop_trigger",
+ "REVOKE_USER_ROLE",
+ "pipesink",
+ "boolean",
+ "datatype",
+ "device",
+ };
+
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ for (String createNodeName : createNodeNames) {
+ String createSql = String.format("CREATE TIMESERIES root.sg1.d1.%s
INT32", createNodeName);
+ String insertSql =
+ String.format("INSERT INTO root.sg1.d1(time, %s) VALUES(1, 1)",
createNodeName);
+ statement.execute(createSql);
+ statement.execute(insertSql);
+ }
+
+ try (ResultSet resultSet = statement.executeQuery("SHOW TIMESERIES")) {
+ Set<String> expectedResult = new
HashSet<>(Arrays.asList(resultTimeseries));
+
+ while (resultSet.next()) {
+
Assert.assertTrue(expectedResult.contains(resultSet.getString("timeseries")));
+ expectedResult.remove(resultSet.getString("timeseries"));
+ }
+ Assert.assertEquals(0, expectedResult.size());
+ }
+
+ for (int i = 0; i < selectNodeNames.length; i++) {
+ String selectSql =
+ String.format("SELECT %s FROM root.sg1.d1 WHERE time = 1",
selectNodeNames[i]);
+ try (ResultSet resultSet = statement.executeQuery(selectSql)) {
+ Assert.assertTrue(resultSet.next());
+ Assert.assertEquals(1, resultSet.getInt("root.sg1.d1." +
suffixInResultColumns[i]));
+ }
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testNodeName() {
+ String[] createNodeNames = {
+ "a_1",
+ "aaa",
+ "`select`",
+ "`a.b`",
+ "`111`",
+ "`a``b`",
+ "`a.\"b`",
+ "`a.'b`",
+ "````",
+ "`c.d.```",
+ "`abc`",
+ };
+
+ String[] resultTimeseries = {
+ "root.sg1.d1.a_1",
+ "root.sg1.d1.aaa",
+ "root.sg1.d1.select",
+ "root.sg1.d1.`a.b`",
+ "root.sg1.d1.`111`",
+ "root.sg1.d1.`a``b`",
+ "root.sg1.d1.`a.\"b`",
+ "root.sg1.d1.`a.'b`",
+ "root.sg1.d1.````",
+ "root.sg1.d1.`c.d.```",
+ "root.sg1.d1.abc",
+ };
+
+ String[] selectNodeNames = {
+ "a_1",
+ "aaa",
+ "`select`",
+ "`a.b`",
+ "`111`",
+ "`a``b`",
+ "`a.\"b`",
+ "`a.'b`",
+ "````",
+ "`c.d.```",
+ "abc",
+ };
+
+ String[] suffixInResultColumns = {
+ "a_1",
+ "aaa",
+ "select",
+ "`a.b`",
+ "`111`",
+ "`a``b`",
+ "`a.\"b`",
+ "`a.'b`",
+ "````",
+ "`c.d.```",
+ "abc",
+ };
+
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ for (String createNodeName : createNodeNames) {
+ String createSql = String.format("CREATE TIMESERIES root.sg1.d1.%s
INT32", createNodeName);
+ String insertSql =
+ String.format("INSERT INTO root.sg1.d1(time, %s) VALUES(1, 1)",
createNodeName);
+ statement.execute(createSql);
+ statement.execute(insertSql);
+ }
+
+ try (ResultSet resultSet = statement.executeQuery("SHOW TIMESERIES")) {
+ Set<String> expectedResult = new
HashSet<>(Arrays.asList(resultTimeseries));
+
+ while (resultSet.next()) {
+
Assert.assertTrue(expectedResult.contains(resultSet.getString("timeseries")));
+ expectedResult.remove(resultSet.getString("timeseries"));
+ }
+ Assert.assertEquals(0, expectedResult.size());
+ }
+
+ for (int i = 0; i < selectNodeNames.length; i++) {
+ String selectSql =
+ String.format("SELECT %s FROM root.sg1.d1 WHERE time = 1",
selectNodeNames[i]);
+ try (ResultSet resultSet = statement.executeQuery(selectSql)) {
+ Assert.assertTrue(resultSet.next());
+ Assert.assertEquals(1, resultSet.getInt("root.sg1.d1." +
suffixInResultColumns[i]));
+ }
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testNodeNameIllegal() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+
+ // nodeName with special characters should be quoted with '`'
+ try {
+ statement.execute("create timeseries root.sg1.d1.`a INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.[a INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.a! INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.a\" INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.a' INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ // nodeName consists of numbers should be quoted with '`'
+ try {
+ statement.execute("create timeseries root.sg1.d1.111 INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.012 INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ // shouled use double '`' in a quoted nodeName
+ try {
+ statement.execute("create timeseries root.sg1.d1.`a`` INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.``a` INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ // unsupported
+ try {
+ statement.execute("create timeseries root.sg1.d1.contains INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.and INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.or INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.not INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ // reserved words can not be identifier
+ try {
+ statement.execute("create timeseries root.sg1.d1.root INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.time INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create timeseries root.sg1.d1.timestamp INT32");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testCreateIllegalStorageGroup() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+
+ try {
+ statement.execute("create storage group root.sg1.d1.");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testExpression() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("CREATE TIMESERIES root.sg1.d1.`1` INT32");
+ statement.execute("CREATE TIMESERIES root.sg1.d1.`a.b` INT32");
+ statement.execute("CREATE TIMESERIES root.sg1.d1.`a.``b` INT32");
+ int pointCnt = 3;
+ for (int i = 0; i < pointCnt; i++) {
+ statement.execute(
+ String.format(
+ "insert into root.sg1.d1(time,%s,%s,%s) values(%d,%d,%d,%d)",
+ "`1`", "`a.b`", "`a.``b`", i, i, i, i));
+ }
+
+ int cnt = 0;
+ try (ResultSet resultSet = statement.executeQuery("SELECT `1` + 1 FROM
root.sg1.d1")) {
+ while (resultSet.next()) {
+ cnt++;
+ }
+ Assert.assertEquals(pointCnt, cnt);
+ }
+
+ cnt = 0;
+ try (ResultSet resultSet =
+ statement.executeQuery("SELECT (`1`*`1`)+1-`a.b` FROM root.sg1.d1
where `1` > 1")) {
+ while (resultSet.next()) {
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ cnt = 0;
+ try (ResultSet resultSet =
+ statement.executeQuery("SELECT (`1`*`1`)+1-`a.b` FROM root.sg1.d1"))
{
+ while (resultSet.next()) {
+ cnt++;
+ }
+ Assert.assertEquals(pointCnt, cnt);
+ }
+
+ cnt = 0;
+ try (ResultSet resultSet =
+ statement.executeQuery("SELECT (`1`*`1`)+1-`a.b` FROM root.sg1.d1
where `1`>0")) {
+ while (resultSet.next()) {
+ cnt++;
+ }
+ Assert.assertEquals(2, cnt);
+ }
+
+ cnt = 0;
+ try (ResultSet resultSet = statement.executeQuery("SELECT avg(`1`)+1
FROM root.sg1.d1")) {
+ while (resultSet.next()) {
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ cnt = 0;
+ try (ResultSet resultSet =
+ statement.executeQuery("SELECT count(`1`)+1 FROM root.sg1.d1 where
`1`>1")) {
+ while (resultSet.next()) {
+ Assert.assertEquals(2.0, resultSet.getDouble(1), 1e-7);
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+
+ cnt = 0;
+ try (ResultSet resultSet = statement.executeQuery("SELECT sin(`1`) + 1
FROM root.sg1.d1")) {
+ while (resultSet.next()) {
+ cnt++;
+ }
+ Assert.assertEquals(pointCnt, cnt);
+ }
+
+ cnt = 0;
+ try (ResultSet resultSet =
+ statement.executeQuery("SELECT sin(`1`) + 1 FROM root.sg1.d1 where
`1`>1")) {
+ while (resultSet.next()) {
+ cnt++;
+ }
+ Assert.assertEquals(1, cnt);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testUDFName() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ String[] udfNames = {"udf", "`udf.test`", "`012`", "`udf```"};
+
+ String[] resultNames = {"udf", "udf.test", "012", "udf`"};
+
+ String createSql = "create function %s as
'org.apache.iotdb.db.query.udf.example.Adder'";
+ for (String udfName : udfNames) {
+ statement.execute(String.format(createSql, udfName));
+ }
+ try (ResultSet resultSet = statement.executeQuery("show functions")) {
+ Set<String> expectedResult = new HashSet<>(Arrays.asList(resultNames));
+ while (resultSet.next()) {
+ if (resultSet.getString(2).equals("external UDTF")) {
+ String udf = resultSet.getString(1).toLowerCase();
+ Assert.assertTrue(expectedResult.contains(udf));
+ expectedResult.remove(udf);
+ }
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+
+ // Illegal Name
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ try {
+ statement.execute("create function udf` as
'org.apache.iotdb.db.query.udf.example.Adder'");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute(
+ "create function ``udf` as
'org.apache.iotdb.db.query.udf.example.Adder'");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create function 111 as
'org.apache.iotdb.db.query.udf.example.Adder'");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create function 'udf' as
'org.apache.iotdb.db.query.udf.example.Adder'");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute(
+ "create function \"udf\" as
'org.apache.iotdb.db.query.udf.example.Adder'");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testUserName() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ String[] userNames =
+ new String[] {
+ "userid",
+ "userid0",
+ "user_id",
+ "user0id",
+ "`22233`",
+ "`userab!`",
+ "`user'ab'`",
+ "`usera.b`",
+ "`usera``b`"
+ };
+
+ String[] resultNames =
+ new String[] {
+ "root",
+ "userid",
+ "userid0",
+ "user_id",
+ "user0id",
+ "22233",
+ "userab!",
+ "user'ab'",
+ "usera.b",
+ "usera`b"
+ };
+
+ String createUsersSql = "create user %s 'pwd123' ";
+ for (String userName : userNames) {
+ statement.execute(String.format(createUsersSql, userName));
+ }
+ Set<String> expectedResult = new HashSet<>(Arrays.asList(resultNames));
+ try (ResultSet resultSet = statement.executeQuery("list user")) {
+ while (resultSet.next()) {
+ String user = resultSet.getString("user").toLowerCase();
+ Assert.assertTrue(expectedResult.contains(user));
+ expectedResult.remove(user);
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+
+ // Illegal names
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ try {
+ statement.execute("create user `abcd`` 'pwd123'");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create user `abcd 'pwd123'");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create user 12345 'pwd123'");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create user a.b.c 'pwd123'");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create user a!@bc 'pwd123'");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testRoleName() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ String[] roleNames =
+ new String[] {
+ "roleid",
+ "roleid0",
+ "role_id",
+ "role0id",
+ "`22233`",
+ "`roleab!`",
+ "`role'ab'`",
+ "`rolea.b`",
+ "`rolea``b`"
+ };
+
+ String[] resultNames =
+ new String[] {
+ "roleid",
+ "roleid0",
+ "role_id",
+ "role0id",
+ "22233",
+ "roleab!",
+ "role'ab'",
+ "rolea.b",
+ "rolea`b"
+ };
+ String createRolesSql = "create role %s";
+ for (String roleName : roleNames) {
+ statement.execute(String.format(createRolesSql, roleName));
+ }
+ Set<String> expectedResult = new HashSet<>(Arrays.asList(resultNames));
+ try (ResultSet resultSet = statement.executeQuery("list role")) {
+ while (resultSet.next()) {
+ String role = resultSet.getString("role").toLowerCase();
+ Assert.assertTrue(expectedResult.contains(role));
+ expectedResult.remove(role);
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+
+ // Illegal names
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ try {
+ statement.execute("create role `abcd``");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create role `abcd");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create role 123456");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create role a.b.c");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ try {
+ statement.execute("create role a!b%c");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ // todo: add this back when supporting trigger in cluster
+
+ // @Test
+ // public void testTriggerName() {
+ // try (Connection connection = EnvFactory.getEnv().getConnection();
+ // Statement statement = connection.createStatement()) {
+ // String[] timeseries = {
+ // "root.vehicle.d1.s1",
+ // "root.vehicle.d1.s2",
+ // "root.vehicle.d1.s3",
+ // "root.vehicle.d1.s4",
+ // "root.vehicle.d1.s5",
+ // };
+ //
+ // String[] triggerNames = {
+ // "`trigger`", "trigger1", "`test```", "`111`", "`[trigger]`",
+ // };
+ //
+ // String[] resultNames = {
+ // "trigger", "trigger1", "test`", "111", "[trigger]",
+ // };
+ //
+ // // show
+ // try (ResultSet resultSet = statement.executeQuery("show triggers")) {
+ // assertFalse(resultSet.next());
+ // }
+ //
+ // String createTimeSereisSql = "CREATE TIMESERIES %s FLOAT";
+ // String createTriggerSql =
+ // "create trigger %s before insert on %s "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator'";
+ // for (int i = 0; i < timeseries.length; ++i) {
+ // statement.execute(String.format(createTimeSereisSql,
timeseries[i]));
+ // statement.execute(String.format(createTriggerSql, triggerNames[i],
timeseries[i]));
+ // }
+ // Set<String> expectedResult = new
HashSet<>(Arrays.asList(resultNames));
+ // try (ResultSet resultSet = statement.executeQuery("show triggers")) {
+ // while (resultSet.next()) {
+ // String trigger = resultSet.getString(1).toLowerCase();
+ // Assert.assertTrue(expectedResult.contains(trigger));
+ // expectedResult.remove(trigger);
+ // }
+ // }
+ // } catch (SQLException e) {
+ // e.printStackTrace();
+ // fail();
+ // }
+ // }
+
+ // @Test
+ // public void testTriggerNameIllegal() {
+ // try (Connection connection = EnvFactory.getEnv().getConnection();
+ // Statement statement = connection.createStatement()) {
+ // try {
+ // statement.execute(
+ // "create trigger trigger` before insert on root.sg1.d1 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator'");
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "create trigger `trigger`` before insert on root.sg1.d1 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator'");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "create trigger 111 before insert on root.sg1.d1 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator'");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "create trigger 'tri' before insert on root.sg1.d1 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator'");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "create trigger \"tri\" before insert on root.sg1.d1 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator'");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // } catch (SQLException e) {
+ // e.printStackTrace();
+ // fail();
+ // }
+ // }
+ //
+
+ // todo: add this back when supporting cq in new cluster
+
+ // @Test
+ // public void testContinuousQueryNameIllegal() {
+ // try (Connection connection = EnvFactory.getEnv().getConnection();
+ // Statement statement = connection.createStatement()) {
+ // try {
+ // statement.execute(
+ // "CREATE CONTINUOUS QUERY `cq1 "
+ // + "BEGIN SELECT max_value(temperature) INTO
temperature_max FROM root.ln.*.*.* "
+ // + "GROUP BY time(1s) END");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "CREATE CONTINUOUS QUERY 111 "
+ // + "BEGIN SELECT max_value(temperature) INTO
temperature_max FROM root.ln.*.*.* "
+ // + "GROUP BY time(1s) END");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "CREATE CONTINUOUS QUERY ``cq1` "
+ // + "BEGIN SELECT max_value(temperature) INTO
temperature_max FROM root.ln.*.*.* "
+ // + "GROUP BY time(1s) END");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "CREATE CONTINUOUS QUERY 'cq1' "
+ // + "BEGIN SELECT max_value(temperature) INTO
temperature_max FROM root.ln.*.*.* "
+ // + "GROUP BY time(1s) END");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "CREATE CONTINUOUS QUERY \"cq1\" "
+ // + "BEGIN SELECT max_value(temperature) INTO
temperature_max FROM root.ln.*.*.* "
+ // + "GROUP BY time(1s) END");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // } catch (SQLException e) {
+ // e.printStackTrace();
+ // fail();
+ // }
+ // }
+
+ // todo: add these back when support sync in new cluster
+
+ // @Test
+ // public void testPipeSinkNameIllegal() {
+ // try (Connection connection = EnvFactory.getEnv().getConnection();
+ // Statement statement = connection.createStatement()) {
+ // try {
+ // statement.execute("CREATE PIPESINK test` AS IoTDB (`ip` =
'127.0.0.1')");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute("CREATE PIPESINK ``test` AS IoTDB (`ip` =
'127.0.0.1')");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute("CREATE PIPESINK test.1 AS IoTDB (`ip` =
'127.0.0.1')");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute("CREATE PIPESINK 12345 AS IoTDB (`ip` =
'127.0.0.1')");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute("CREATE PIPESINK a!@cb AS IoTDB (`ip` =
'127.0.0.1')");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // } catch (SQLException e) {
+ // e.printStackTrace();
+ // fail();
+ // }
+ // }
+
+ // todo: add this back when support template in new cluster
+
+ // @Test
+ // public void testTemplateName() {
+ // String[] templateNames = {
+ // "id",
+ // "ID",
+ // "id0",
+ // "_id",
+ // "0id",
+ // "`233`",
+ // "`ab!`",
+ // "`\"ab\"`",
+ // "`\\\"ac\\\"`",
+ // "`'ab'`",
+ // "`a.b`",
+ // "`a``b`"
+ // };
+ //
+ // String[] resultNames = {
+ // "id", "ID", "id0", "_id", "0id", "233", "ab!", "\"ab\"",
"\\\"ac\\\"", "'ab'", "a.b",
+ // "a`b"
+ // };
+ //
+ // try (Connection connection = EnvFactory.getEnv().getConnection();
+ // Statement statement = connection.createStatement()) {
+ // for (String templateName : templateNames) {
+ // String createTemplateSql =
+ // String.format(
+ // "create schema template %s (temperature FLOAT
encoding=RLE, status BOOLEAN
+ // encoding=PLAIN compression=SNAPPY)",
+ // templateName);
+ // statement.execute(createTemplateSql);
+ // }
+ //
+ // try (ResultSet resultSet = statement.executeQuery("SHOW TEMPLATES"))
{
+ // Set<String> expectedResult = new
HashSet<>(Arrays.asList(resultNames));
+ // while (resultSet.next()) {
+ //
Assert.assertTrue(expectedResult.contains(resultSet.getString("template
name")));
+ // expectedResult.remove(resultSet.getString("template name"));
+ // }
+ // Assert.assertEquals(0, expectedResult.size());
+ // }
+ // } catch (SQLException e) {
+ // e.printStackTrace();
+ // fail();
+ // }
+ // }
+ //
+ // @Test
+ // public void testTemplateNameIllegal() {
+ // try (Connection connection = EnvFactory.getEnv().getConnection();
+ // Statement statement = connection.createStatement()) {
+ // try {
+ // statement.execute(
+ // "create schema template `a`` "
+ // + "(temperature FLOAT encoding=RLE, status BOOLEAN
encoding=PLAIN
+ // compression=SNAPPY)");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "create schema template 111 "
+ // + "(temperature FLOAT encoding=RLE, status BOOLEAN
encoding=PLAIN
+ // compression=SNAPPY)");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "create schema template `a "
+ // + "(temperature FLOAT encoding=RLE, status BOOLEAN
encoding=PLAIN
+ // compression=SNAPPY)");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "create schema template 'a' "
+ // + "(temperature FLOAT encoding=RLE, status BOOLEAN
encoding=PLAIN
+ // compression=SNAPPY)");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // try {
+ // statement.execute(
+ // "create schema template \"a\" "
+ // + "(temperature FLOAT encoding=RLE, status BOOLEAN
encoding=PLAIN
+ // compression=SNAPPY)");
+ // fail();
+ // } catch (Exception ignored) {
+ // }
+ //
+ // } catch (SQLException e) {
+ // e.printStackTrace();
+ // fail();
+ // }
+ // }
+}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSyntaxConventionStringLiteralIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSyntaxConventionStringLiteralIT.java
new file mode 100644
index 0000000000..1278436bf8
--- /dev/null
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSyntaxConventionStringLiteralIT.java
@@ -0,0 +1,705 @@
+/*
+ * 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.it;
+
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.env.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+import
org.apache.iotdb.itbase.constant.BuiltinTimeSeriesGeneratingFunctionEnum;
+import org.apache.iotdb.itbase.constant.TestConstant;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+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.assertTrue;
+import static org.junit.Assert.fail;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({LocalStandaloneIT.class, ClusterIT.class})
+public class IoTDBSyntaxConventionStringLiteralIT {
+
+ @Before
+ public void setUp() throws Exception {
+ EnvFactory.getEnv().initBeforeTest();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ EnvFactory.getEnv().cleanAfterTest();
+ }
+
+ /** Legal cases of using StringLiteral with single quote in insert and
select clause. */
+ @Test
+ public void testStringLiteralWithSingleQuote() {
+ String[] insertData = {
+ "'string'",
+ "'`string`'",
+ "'``string'",
+ "'\"string\"'",
+ "'\"\"string'",
+ "'\\\"string\\\"'",
+ "'''string'",
+ "'\\'string'",
+ "'\\nstring'",
+ "'\\rstring'",
+ "'@#$%^&*()string'",
+ };
+
+ String[] resultData = {
+ "string",
+ "`string`",
+ "``string",
+ "\"string\"",
+ "\"\"string",
+ "\"string\"",
+ "'string",
+ "'string",
+ "\\nstring",
+ "\\rstring",
+ "@#$%^&*()string",
+ };
+
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("CREATE TIMESERIES root.sg1.d1.s1 TEXT");
+ for (int i = 0; i < insertData.length; i++) {
+ String insertSql =
+ String.format("INSERT INTO root.sg1.d1(time, s1) values (%d, %s)",
i, insertData[i]);
+ statement.execute(insertSql);
+ }
+
+ try (ResultSet resultSet = statement.executeQuery("SELECT s1 FROM
root.sg1.d1")) {
+ int cnt = 0;
+ while (resultSet.next()) {
+ Assert.assertEquals(resultData[cnt],
resultSet.getString("root.sg1.d1.s1"));
+ cnt++;
+ }
+ Assert.assertEquals(insertData.length, cnt);
+ }
+
+ for (String insertDatum : insertData) {
+ String querySql = String.format("SELECT s1 FROM root.sg1.d1 WHERE s1 =
%s", insertDatum);
+ try (ResultSet resultSet = statement.executeQuery(querySql)) {
+ Assert.assertTrue(resultSet.next());
+ }
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ /** Legal cases of using StringLiteral with double quote in insert and
select clause. */
+ @Test
+ public void testStringLiteralWithDoubleQuote() {
+ String[] insertData = {
+ "\"string\"",
+ "\"`string`\"",
+ "\"``string\"",
+ "\"'string'\"",
+ "\"''string\"",
+ "\"\\'string\\'\"",
+ "\"\"\"string\"",
+ "\"\\\"string\"",
+ "\"\\nstring\"",
+ "\"\\rstring\"",
+ "\"@#$%^&*()string\"",
+ };
+
+ String[] resultData = {
+ "string",
+ "`string`",
+ "``string",
+ "'string'",
+ "''string",
+ "'string'",
+ "\"string",
+ "\"string",
+ "\\nstring",
+ "\\rstring",
+ "@#$%^&*()string",
+ };
+
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("CREATE TIMESERIES root.sg1.d1.s1 TEXT");
+ for (int i = 0; i < insertData.length; i++) {
+ String insertSql =
+ String.format("INSERT INTO root.sg1.d1(time, s1) values (%d, %s)",
i, insertData[i]);
+ statement.execute(insertSql);
+ }
+
+ try (ResultSet resultSet = statement.executeQuery("SELECT s1 FROM
root.sg1.d1")) {
+ int cnt = 0;
+ while (resultSet.next()) {
+ Assert.assertEquals(resultData[cnt],
resultSet.getString("root.sg1.d1.s1"));
+ cnt++;
+ }
+ Assert.assertEquals(insertData.length, cnt);
+ }
+
+ for (String insertDatum : insertData) {
+ String querySql = String.format("SELECT s1 FROM root.sg1.d1 WHERE s1 =
%s", insertDatum);
+ try (ResultSet resultSet = statement.executeQuery(querySql)) {
+ Assert.assertTrue(resultSet.next());
+ }
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testStringLiteralIllegalCase() {
+ String errorMsg =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:45 no viable alternative at input '(1, string'";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("CREATE TIMESERIES root.sg1.d1.s1 TEXT");
+ } catch (SQLException e) {
+ fail(e.getMessage());
+ }
+ // without ' or "
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("INSERT INTO root.sg1.d1(time, s1) values (1,
string)");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg, e.getMessage());
+ }
+
+ String errorMsg1 =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:45 no viable alternative at input '(1, `string`'";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ // wrap STRING_LITERAL with ``
+ statement.execute("INSERT INTO root.sg1.d1(time, s1) values (1,
`string`)");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg1, e.getMessage());
+ }
+
+ String errorMsg2 =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:53 token recognition error at: '')'";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ // single ' in ''
+ statement.execute("INSERT INTO root.sg1.d1(time, s1) values (1,
''string')");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg2, e.getMessage());
+ }
+
+ String errorMsg3 =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:53 token recognition error at: '\")'";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ // single " in ""
+ statement.execute("INSERT INTO root.sg1.d1(time, s1) values (1,
\"\"string\")");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg3, e.getMessage());
+ }
+ }
+
+ /**
+ * LOAD/REMOVE/SETTLE use STRING_LITERAL to represent file path legal cases
are in
+ * IoTDBLoadExternalTsfileIT
+ */
+ @Test
+ public void testIllegalFilePath() {
+ String errorMsg =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:5 no viable alternative at input 'LOAD path'";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("LOAD path");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg, e.getMessage());
+ }
+
+ String errorMsg1 =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:7 mismatched input 'path' expecting STRING_LITERAL";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("REMOVE path");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg1, e.getMessage());
+ }
+
+ String errorMsg2 =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:7 mismatched input 'path' expecting {ROOT,
STRING_LITERAL}";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("SETTLE path");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg2, e.getMessage());
+ }
+ }
+
+ @Test
+ public void testUserPassword() {
+ String errorMsg =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:18 mismatched input 'test' expecting STRING_LITERAL";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("CREATE USER test1 'test'");
+ // password should be STRING_LITERAL
+ statement.execute("CREATE USER test1 test");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg, e.getMessage());
+ }
+
+ String errorMsg1 =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:17 mismatched input '`test`' expecting STRING_LITERAL";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("CREATE USER test \"test\"");
+ // password should be STRING_LITERAL
+ statement.execute("CREATE USER test `test`");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg1, e.getMessage());
+ }
+ }
+
+ @Test
+ public void testUDFClassName() {
+ String errorMsg =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:23 mismatched input 'org' expecting STRING_LITERAL";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ // udf class name should be STRING_LITERAL
+ statement.execute("create function udf as
'org.apache.iotdb.db.query.udf.example.Adder'");
+
+ // executed correctly
+ try (ResultSet resultSet = statement.executeQuery("show functions")) {
+ assertEquals(3, resultSet.getMetaData().getColumnCount());
+ int count = 0;
+ while (resultSet.next()) {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); ++i) {
+ stringBuilder.append(resultSet.getString(i)).append(",");
+ }
+ String result = stringBuilder.toString();
+ if (result.contains(TestConstant.FUNCTION_TYPE_NATIVE)) {
+ continue;
+ }
+ ++count;
+ }
+ Assert.assertEquals(1 +
BuiltinTimeSeriesGeneratingFunctionEnum.values().length, count);
+ }
+ statement.execute("drop function udf");
+
+ // without '' or ""
+ statement.execute("create function udf as
org.apache.iotdb.db.query.udf.example.Adder");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg, e.getMessage());
+ }
+
+ // Illegal name with back quote
+ String errorMsg1 =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:23 mismatched input
'`org.apache.iotdb.db.query.udf.example.Adder`' "
+ + "expecting STRING_LITERAL";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ // udf class name should be STRING_LITERAL
+ statement.execute("create function udf as
`org.apache.iotdb.db.query.udf.example.Adder`");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg1, e.getMessage());
+ }
+ }
+
+ @Test
+ public void testUDFAttribute() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("CREATE TIMESERIES root.vehicle.d1.s1 FLOAT");
+ statement.execute("INSERT INTO root.vehicle.d1(time,s1) values
(1,2.0),(2,3.0)");
+
+ try (ResultSet resultSet =
+ statement.executeQuery("select bottom_k(s1,'k' = '1') from
root.vehicle.d1")) {
+ assertTrue(resultSet.next());
+ Assert.assertEquals("2.0", resultSet.getString(2));
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+
+ // Illegal attribute
+ String errorMsg =
+ "401: Error occurred while parsing SQL to physical plan: "
+ + "line 1:21 extraneous input 'k' expecting {',', ')'}";
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ // UDF attribute should be STRING_LITERAL
+ statement.executeQuery("select bottom_k(s1,``k` = 1) from
root.vehicle.d1");
+ fail();
+ } catch (SQLException e) {
+ Assert.assertEquals(errorMsg, e.getMessage());
+ }
+ }
+
+ @Test
+ public void testCreateTimeSeriesAttribute() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ // besides datatype,encoding,compression,compressor, attributes in
create time series clause
+ // could be STRING_LITERAL
+ statement.execute(
+ "create timeseries root.vehicle.d1.s1 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s2 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY,
max_point_number = 5");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s3 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY,
'max_point_number' = '5'");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s4 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY,
max_point_number = '5'");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s5 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY,
`max_point_number` = 5");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s6 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY,
`max_point_number` = `5`");
+ try (ResultSet resultSet = statement.executeQuery("show timeseries")) {
+ int cnt = 0;
+ while (resultSet.next()) {
+ cnt++;
+ }
+ Assert.assertEquals(6, cnt);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testCreateTimeSeriesTags() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute(
+ "create timeseries root.vehicle.d1.s1 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "tags(tag1=v1)");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s2 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "tags(`tag1`=v1)");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s3 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "tags('tag1'=v1)");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s4 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "tags(\"tag1\"=v1)");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s5 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "tags(tag1=`v1`)");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s6 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "tags(tag1='v1')");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s7 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "tags(tag1=\"v1\")");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s8 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "tags(tag1=v1)");
+ try (ResultSet resultSet = statement.executeQuery("show timeseries")) {
+ int cnt = 0;
+ while (resultSet.next()) {
+ cnt++;
+ }
+ Assert.assertEquals(8, cnt);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testCreateTimeSeriesAttributeClause() {
+
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute(
+ "create timeseries root.vehicle.d1.s1 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "attributes('attr1'='v1', 'attr2'='v2')");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s2 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "attributes(attr1=v1, attr2=v2)");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s3 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "attributes(`attr1`=`v1`, `attr2`=v2)");
+ statement.execute(
+ "create timeseries root.vehicle.d1.s4 "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY "
+ + "attributes('attr1'=v1, attr2=v2)");
+ try (ResultSet resultSet = statement.executeQuery("show timeseries")) {
+ int cnt = 0;
+ while (resultSet.next()) {
+ cnt++;
+ }
+ Assert.assertEquals(4, cnt);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ // alias can be identifier or STRING_LITERAL
+ @Test
+ public void testAliasInResultColumn() {
+ String[] alias = {
+ "b", "test", "`test.1`", "`1``1`", "'test'", "\"test\"", "\"\\\\test\"",
+ };
+
+ String[] res = {
+ "b", "test", "test.1", "1`1", "test", "test", "\\\\test",
+ };
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute(
+ "create timeseries root.sg.a "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY ");
+ statement.execute("insert into root.sg(time, a) values (1,1)");
+
+ String selectSql = "select a as %s from root.sg";
+ for (int i = 0; i < alias.length; i++) {
+ try (ResultSet resultSet =
statement.executeQuery(String.format(selectSql, alias[i]))) {
+ Assert.assertEquals(res[i],
resultSet.getMetaData().getColumnName(2));
+ }
+ }
+
+ try {
+ statement.execute("select a as test.b from root.sg");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Test
+ public void testAliasInAlterClause() {
+ String[] alias = {
+ "b", "test", "`test.1`", "`1``1`", "'test'", "\"test\"", "\"\\\\test\"",
+ };
+
+ String[] res = {
+ "b", "test", "test.1", "1`1", "test", "test", "\\\\test",
+ };
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute(
+ "create timeseries root.sg.a "
+ + "with datatype=INT64, encoding=PLAIN, compression=SNAPPY ");
+
+ String alterSql = "ALTER timeseries root.sg.a UPSERT alias = %s";
+ for (int i = 0; i < alias.length; i++) {
+ statement.execute(String.format(alterSql, alias[i]));
+ try (ResultSet resultSet = statement.executeQuery("show timeseries")) {
+ resultSet.next();
+ Assert.assertEquals(res[i], resultSet.getString("alias"));
+ }
+ }
+
+ try {
+ statement.execute("ALTER timeseries root.sg.a UPSERT alias = test.a");
+ fail();
+ } catch (Exception ignored) {
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ // TODO: add this back when trigger is supported in new cluster
+
+ // @Test
+ // public void testTriggerClassName() {
+ // String errorMsg =
+ // "401: Error occurred while parsing SQL to physical plan: "
+ // + "line 1:64 mismatched input 'org' expecting {AS, '.'}";
+ // try (Connection connection = EnvFactory.getEnv().getConnection();
+ // Statement statement = connection.createStatement()) {
+ // // show
+ // ResultSet resultSet = statement.executeQuery("show triggers");
+ // assertFalse(resultSet.next());
+ //
+ // statement.execute("CREATE TIMESERIES root.vehicle.d1.s1 FLOAT");
+ // statement.execute("CREATE TIMESERIES root.vehicle.d1.s2 FLOAT");
+ // statement.execute("CREATE TIMESERIES root.vehicle.d1.s3 FLOAT");
+ // // create trigger, trigger class name should be STRING_LITERAL
+ // statement.execute(
+ // "create trigger trigger_1 before insert on root.vehicle.d1.s1 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator'");
+ // statement.execute(
+ // "create trigger trigger_2 after insert on root.vehicle.d1.s2 "
+ // + "as 'org.apache.iotdb.db.engine.trigger.example.Counter'");
+ //
+ // // show
+ // resultSet = statement.executeQuery("show triggers");
+ // assertTrue(resultSet.next());
+ // assertTrue(resultSet.next());
+ // assertFalse(resultSet.next());
+ //
+ // // show
+ // resultSet = statement.executeQuery("show triggers");
+ // assertTrue(resultSet.next());
+ // assertTrue(resultSet.next());
+ // assertFalse(resultSet.next());
+ //
+ // statement.execute(
+ // "create trigger trigger_1 before insert on root.vehicle.d1.s3 "
+ // + "as
org.apache.iotdb.db.engine.trigger.example.Accumulator");
+ // fail();
+ // } catch (SQLException e) {
+ // Assert.assertEquals(errorMsg, e.getMessage());
+ // }
+ // }
+ //
+ // @Test
+ // public void testTriggerClassName1() {
+ // String errorMsg =
+ // "401: Error occurred while parsing SQL to physical plan: "
+ // + "line 1:64 mismatched input
+ // '`org.apache.iotdb.db.engine.trigger.example.Accumulator`' "
+ // + "expecting {AS, '.'}";
+ // try (Connection connection = EnvFactory.getEnv().getConnection();
+ // Statement statement = connection.createStatement()) {
+ // statement.execute("CREATE TIMESERIES root.vehicle.d1.s1 FLOAT");
+ // statement.execute(
+ // "create trigger trigger_1 before insert on root.vehicle.d1.s1 "
+ // + "as
`org.apache.iotdb.db.engine.trigger.example.Accumulator`");
+ // fail();
+ // } catch (SQLException e) {
+ // Assert.assertEquals(errorMsg, e.getMessage());
+ // }
+ // }
+ //
+ // // attribute can be constant | identifier
+ // @Test
+ // public void testTriggerAttribute() {
+ // try (Connection connection = EnvFactory.getEnv().getConnection();
+ // Statement statement = connection.createStatement()) {
+ // statement.execute("CREATE TIMESERIES root.vehicle.d1.s1 FLOAT");
+ // statement.execute("CREATE TIMESERIES root.vehicle.d1.s2 FLOAT");
+ // statement.execute("CREATE TIMESERIES root.vehicle.d1.s3 FLOAT");
+ // statement.execute("CREATE TIMESERIES root.vehicle.d1.s4 FLOAT");
+ // statement.execute("CREATE TIMESERIES root.vehicle.d1.s5 FLOAT");
+ // statement.execute("CREATE TIMESERIES root.vehicle.d1.s6 FLOAT");
+ // // trigger attribute should be STRING_LITERAL
+ // statement.execute(
+ // "create trigger trigger_1 before insert on root.vehicle.d1.s1 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator' with ('k1'='v1')");
+ //
+ // statement.execute(
+ // "create trigger trigger_2 before insert on root.vehicle.d1.s2 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator' with (k1='v1')");
+ //
+ // statement.execute(
+ // "create trigger trigger_3 before insert on root.vehicle.d1.s3 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator' with ('k1'=v1)");
+ //
+ // statement.execute(
+ // "create trigger trigger_4 before insert on root.vehicle.d1.s4 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator' with (k1=v1)");
+ //
+ // statement.execute(
+ // "create trigger trigger_5 before insert on root.vehicle.d1.s5 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator' with (`k1`=`v1`)");
+ //
+ // statement.execute(
+ // "create trigger trigger_6 before insert on root.vehicle.d1.s6 "
+ // + "as
'org.apache.iotdb.db.engine.trigger.example.Accumulator' with (`k1`=v1)");
+ //
+ // boolean hasResult = statement.execute("show triggers");
+ // assertTrue(hasResult);
+ // } catch (SQLException e) {
+ // e.printStackTrace();
+ // fail();
+ // }
+ // }
+
+ // todo: add this back when supporting sync in new cluster
+
+ // @Test
+ // public void testPipeSinkAttribute() {
+ // String errorMsg =
+ // "401: Error occurred while parsing SQL to physical plan: "
+ // + "line 1:40 token recognition error at: '` = '127.0.0.1')'";
+ // try (Connection connection = EnvFactory.getEnv().getConnection();
+ // Statement statement = connection.createStatement()) {
+ // statement.execute("CREATE PIPESINK `test.*1` AS IoTDB (``ip` =
'127.0.0.1')");
+ // fail();
+ // } catch (SQLException e) {
+ // Assert.assertEquals(errorMsg, e.getMessage());
+ // }
+ // }
+}