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());
+  //    }
+  //  }
+}

Reply via email to