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

rong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 9ebd02c  [IOTDB-2429] Fix string literal constant being treated as 
node name (#4880)
9ebd02c is described below

commit 9ebd02c600ffa13055e8669804c8dd563f815b2c
Author: BaiJian <[email protected]>
AuthorDate: Wed Jan 19 09:38:29 2022 +0800

    [IOTDB-2429] Fix string literal constant being treated as node name (#4880)
---
 .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4   |  2 +-
 docs/UserGuide/Reference/Syntax-Conventions.md     | 15 ++++++----
 docs/zh/UserGuide/Reference/Syntax-Conventions.md  | 13 ++++----
 .../db/integration/IoTDBSyntaxConventionIT.java    | 35 ++++++++++++++++++++--
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    |  4 +--
 .../dataset/groupby/GroupByLevelDataSetTest.java   |  2 +-
 .../dataset/groupby/GroupByTimeDataSetTest.java    |  2 +-
 7 files changed, 54 insertions(+), 19 deletions(-)

diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 
b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index 14cb829..aafc553 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -696,8 +696,8 @@ suffixPathCanInExpr
 nodeNameCanInExpr
     : wildcard
     | wildcard? ID wildcard?
+    | QUTOED_ID
     | QUTOED_ID_WITHOUT_DOT
-    | STRING_LITERAL
     ;
 
 wildcard
diff --git a/docs/UserGuide/Reference/Syntax-Conventions.md 
b/docs/UserGuide/Reference/Syntax-Conventions.md
index 6a32d99..14230ea 100644
--- a/docs/UserGuide/Reference/Syntax-Conventions.md
+++ b/docs/UserGuide/Reference/Syntax-Conventions.md
@@ -171,12 +171,15 @@ Certain keywords, such as TIME and ROOT, are reserved and 
cannot use as identifi
 
 IoTDB supports the execution of arbitrary nested expressions consisting of 
numbers, time series, arithmetic expressions, and time series generating 
functions (including user-defined functions) in the `select` clause.
 
-Note: Node names that consist solely of digits in an expression must be 
enclosed in backticks (`).
+Note: Node names that consist solely of digits, `'` and `"` in an expression 
must be enclosed in backticks (`).
 ```sql
-// There is a time series: root.sg.d.0
-select 0 from root.sg.d  // ambiguity exists, parsing failed
-select `0` from root.sg.d  // query from root.sg.d.0
-select `0` + 0 from root.sg.d  // valid expression
+-- There exists timeseries: root.sg.d.0, root.sg.d.'a' and root.sg."d".b
+select 0 from root.sg.d  -- ambiguity exists, parsing failed
+select 'a' from root.sg.d -- ambiguity exists, parsing failed
+select "d".b from root.sg -- ambiguity exists, parsing failed
+select `0` from root.sg.d  -- query from root.sg.d.0
+select `0` + 0 from root.sg.d -- valid expression, add number 0 to each point 
of root.sg.d.0
+select myudf(`'a'`, 'x') from root.sg.d -- valid expression, call function 
myudf with timeseries root.sg.d.'a' as the 1st parameter, and a string constant 
'x' as the 2nd parameter
 ```
 
 ## Learn More
@@ -185,4 +188,4 @@ Please read the lexical and grammar description files in 
our code repository:
 
 Lexical file: 
`antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlLexer.g4`
 
-Grammer file: 
`antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4`
\ No newline at end of file
+Grammer file: 
`antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4`
diff --git a/docs/zh/UserGuide/Reference/Syntax-Conventions.md 
b/docs/zh/UserGuide/Reference/Syntax-Conventions.md
index b3846cd..b93a27c 100644
--- a/docs/zh/UserGuide/Reference/Syntax-Conventions.md
+++ b/docs/zh/UserGuide/Reference/Syntax-Conventions.md
@@ -170,12 +170,15 @@ CREATE TIMESERIES root.a.b."s1.s2".c WITH DATATYPE=INT32, 
ENCODING=RLE
 
 IoTDB 支持在 `select` 子句中执行由数字常量、时间序列、算数运算表达式和时间序列生成函数(包括用户自定义函数)组成的任意嵌套表达式。
 
-注意:当参与表达式的路径节点名由纯数字组成(不推荐!)时,必须使用反引号(`)括起,以免引起歧义。示例如下:
+注意:当参与表达式的路径节点名由纯数字、单引号、或双引号组成(不推荐!)时,必须使用反引号(`)括起,以免引起歧义。示例如下:
 ```sql
-// 存在时间序列: root.sg.d.0
-select 0 from root.sg.d  // 存在歧义,解析失败
-select `0` from root.sg.d  // 对时间序列 root.sg.d.0 进行查询
-select `0` + 0 from root.sg.d  // 表达式,对时间序列 root.sg.d.0 的每一个查询结果加 0
+-- 存在时间序列: root.sg.d.0, root.sg.d.'a' 和 root.sg."d".b
+select 0 from root.sg.d  -- 存在歧义,解析失败
+select 'a' from root.sg.d -- 存在歧义,解析失败
+select "d".b from root.sg -- 存在歧义,解析失败
+select `0` from root.sg.d  -- 对时间序列 root.sg.d.0 进行查询
+select `0` + 0 from root.sg.d -- 表达式,对时间序列 root.sg.d.0 的每一个查询结果加 0
+select myudf(`'a'`, 'x') from root.sg.d -- 表达式,调用函数 myudf,第一个参数为时间序列 
root.sg.d.'a',第二个参数为字符串常量 'x'
 ```
 
 ## 了解更多
diff --git 
a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSyntaxConventionIT.java
 
b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSyntaxConventionIT.java
index 217bf4f..ad62e8c 100644
--- 
a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSyntaxConventionIT.java
+++ 
b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSyntaxConventionIT.java
@@ -33,7 +33,9 @@ import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 
 import static org.junit.Assert.fail;
 
@@ -218,10 +220,37 @@ public class IoTDBSyntaxConventionIT {
   }
 
   @Test
+  public void testIllegalExpression4() {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute("CREATE TIMESERIES root.sg1.d1.`'a'` INT64");
+      try {
+        statement.execute("SELECT 'a' FROM root.sg1.d1");
+        fail();
+      } catch (SQLException e) {
+        // ignored
+      }
+    } catch (SQLException e) {
+      e.printStackTrace();
+      fail();
+    }
+  }
+
+  @Test
   public void testNodeName() {
     String[] createNodeNames = {
       "`select`", "'select'", "\"select\"", "`a+b`", "'a+b'", "\"a+b\"", 
"'a.b'", "\"a.b\""
     };
+    String[] selectNodeNames = {
+      "`select`",
+      "`'select'`",
+      "`\"select\"`",
+      "`a+b`",
+      "`'a+b'`",
+      "`\"a+b\"`",
+      "`'a.b'`",
+      "`\"a.b\"`"
+    };
     String[] resultNodeNames = {
       "select", "'select'", "\"select\"", "a+b", "'a+b'", "\"a+b\"", "'a.b'", 
"\"a.b\""
     };
@@ -258,9 +287,9 @@ public class IoTDBSyntaxConventionIT {
       }
       Assert.assertEquals(0, expectedResult.size());
 
-      for (int i = 0; i < createNodeNames.length; i++) {
+      for (int i = 0; i < selectNodeNames.length; i++) {
         String selectSql =
-            String.format("SELECT %s FROM root.sg1.d1 WHERE time = 1", 
createNodeNames[i]);
+            String.format("SELECT %s FROM root.sg1.d1 WHERE time = 1", 
selectNodeNames[i]);
         System.out.println("SELECT STATEMENT: " + selectSql);
         hasResult = statement.execute(selectSql);
         Assert.assertTrue(hasResult);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java 
b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
index 2933d9a..f9a494a 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java
@@ -2204,8 +2204,8 @@ public class IoTDBSqlVisitor extends 
IoTDBSqlParserBaseVisitor<Operator> {
   public String parseNodeNameCanInExpr(IoTDBSqlParser.NodeNameCanInExprContext 
ctx) {
     if (ctx.QUTOED_ID_WITHOUT_DOT() != null) {
       return parseStringWithQuotes(ctx.QUTOED_ID_WITHOUT_DOT().getText());
-    } else if (ctx.STRING_LITERAL() != null) {
-      return parseStringWithQuotesInNodeName(ctx.STRING_LITERAL().getText());
+    } else if (ctx.QUTOED_ID() != null) {
+      return parseStringWithQuotes(ctx.QUTOED_ID().getText());
     } else {
       return ctx.getText();
     }
diff --git 
a/server/src/test/java/org/apache/iotdb/db/query/dataset/groupby/GroupByLevelDataSetTest.java
 
b/server/src/test/java/org/apache/iotdb/db/query/dataset/groupby/GroupByLevelDataSetTest.java
index 03cd7c4..7924a31 100644
--- 
a/server/src/test/java/org/apache/iotdb/db/query/dataset/groupby/GroupByLevelDataSetTest.java
+++ 
b/server/src/test/java/org/apache/iotdb/db/query/dataset/groupby/GroupByLevelDataSetTest.java
@@ -143,7 +143,7 @@ public class GroupByLevelDataSetTest {
     queryPlan =
         (QueryPlan)
             processor.parseSQLToPhysicalPlan(
-                "select count(\"s3+xy\") from root.test.* group by level=2");
+                "select count(`\"s3+xy\"`) from root.test.* group by level=2");
     dataSet = queryExecutor.processQuery(queryPlan, 
EnvironmentUtils.TEST_QUERY_CONTEXT);
 
     assertTrue(dataSet.hasNext());
diff --git 
a/server/src/test/java/org/apache/iotdb/db/query/dataset/groupby/GroupByTimeDataSetTest.java
 
b/server/src/test/java/org/apache/iotdb/db/query/dataset/groupby/GroupByTimeDataSetTest.java
index 30f3468..d0388fe 100644
--- 
a/server/src/test/java/org/apache/iotdb/db/query/dataset/groupby/GroupByTimeDataSetTest.java
+++ 
b/server/src/test/java/org/apache/iotdb/db/query/dataset/groupby/GroupByTimeDataSetTest.java
@@ -172,7 +172,7 @@ public class GroupByTimeDataSetTest {
     queryPlan =
         (QueryPlan)
             processor.parseSQLToPhysicalPlan(
-                "select count(\"s3+xy\") from root.test.* group by ([0,20), 
3ms, 10ms), level=2");
+                "select count(`\"s3+xy\"`) from root.test.* group by ([0,20), 
3ms, 10ms), level=2");
     dataSet = queryExecutor.processQuery(queryPlan, 
EnvironmentUtils.TEST_QUERY_CONTEXT);
 
     assertTrue(dataSet.hasNext());

Reply via email to