You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ro...@apache.org on 2022/05/23 02:43:47 UTC

[iotdb] branch master updated: [IOTDB-3069] unescape string in IoTDBSqlVisitor and ASTVisitor (#5952)

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 c053a2a766 [IOTDB-3069] unescape string in IoTDBSqlVisitor and ASTVisitor (#5952)
c053a2a766 is described below

commit c053a2a766d37d128a13eb18be4479351cb0bbf5
Author: Liao Lanyu <48...@users.noreply.github.com>
AuthorDate: Mon May 23 10:43:43 2022 +0800

    [IOTDB-3069] unescape string in IoTDBSqlVisitor and ASTVisitor (#5952)
    
    Description: ParseStringLiteral in IoTDBSqlVisitor and ASTVisitor will not unescape string content
---
 .../antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4  |  6 ++---
 .../iotdb/db/integration/IoTDBFuzzyQueryIT.java    |  4 +--
 .../IoTDBSyntaxConventionStringLiteralIT.java      | 12 ++++-----
 .../db/integration/IoTDBUDTFBuiltinFunctionIT.java |  2 +-
 .../org/apache/iotdb/commons/path/PartialPath.java |  7 ++++++
 .../iotdb/db/mpp/plan/parser/ASTVisitor.java       | 29 ++++++++++++++++++----
 .../apache/iotdb/db/qp/sql/IoTDBSqlVisitor.java    | 29 ++++++++++++++++++----
 7 files changed, 67 insertions(+), 22 deletions(-)

diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
index 04bad754a2..fc114ebe63 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
@@ -1005,15 +1005,15 @@ fragment CN_CHAR
     ;
 
 fragment DQUOTA_STRING
-    : '"' ( '\\'. | '""' | ~('"'| '\\') )* '"'
+    : '"' ( '\\'. | '""' | ~('"') )* '"'
     ;
 
 fragment SQUOTA_STRING
-    : '\'' ( '\\'. | '\'\'' |~('\''| '\\') )* '\''
+    : '\'' ( '\\'. | '\'\'' |~('\'') )* '\''
     ;
 
 fragment BQUOTA_STRING
-    : '`' ( '\\' ~('`') | '``' | ~('`'| '\\') )* '`'
+    : '`' ( '\\' ~('`') | '``' | ~('`') )* '`'
     ;
 
 
diff --git a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBFuzzyQueryIT.java b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBFuzzyQueryIT.java
index 9e99f60e9e..8c61c4b89d 100644
--- a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBFuzzyQueryIT.java
+++ b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBFuzzyQueryIT.java
@@ -123,7 +123,7 @@ public class IoTDBFuzzyQueryIT {
     hasResultSet = st0.execute("select status from root.t1.wf01.wt01 where status like '%'");
     Assert.assertTrue(hasResultSet);
     Assert.assertEquals(
-        "1,14,616,626,6116,6%16,8[sS]*,%123,123%,\\", outputResultStr(st0.getResultSet()));
+        "1,14,616,626,6116,6%16,8[sS]*,%123,123%,\\\\", outputResultStr(st0.getResultSet()));
 
     hasResultSet = st0.execute("select status from root.t1.wf01.wt01 where status like '1%'");
     Assert.assertTrue(hasResultSet);
@@ -160,7 +160,7 @@ public class IoTDBFuzzyQueryIT {
     hasResultSet =
         st0.execute("select status from root.t1.wf01.wt01 where status like '%\\\\\\\\%'");
     Assert.assertTrue(hasResultSet);
-    Assert.assertEquals("\\", outputResultStr(st0.getResultSet()));
+    Assert.assertEquals("\\\\", outputResultStr(st0.getResultSet()));
   }
 
   @Test(expected = Exception.class)
diff --git a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSyntaxConventionStringLiteralIT.java b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSyntaxConventionStringLiteralIT.java
index 957c967453..5b971c51ef 100644
--- a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSyntaxConventionStringLiteralIT.java
+++ b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBSyntaxConventionStringLiteralIT.java
@@ -80,8 +80,8 @@ public class IoTDBSyntaxConventionStringLiteralIT {
       "\"string\"",
       "'string",
       "'string",
-      "\nstring",
-      "\rstring",
+      "\\nstring",
+      "\\rstring",
       "@#$%^&*()string",
     };
 
@@ -148,8 +148,8 @@ public class IoTDBSyntaxConventionStringLiteralIT {
       "'string'",
       "\"string",
       "\"string",
-      "\nstring",
-      "\rstring",
+      "\\nstring",
+      "\\rstring",
       "@#$%^&*()string",
     };
 
@@ -697,7 +697,7 @@ public class IoTDBSyntaxConventionStringLiteralIT {
     };
 
     String[] res = {
-      "b", "test", "test.1", "1`1", "test", "test", "\\test",
+      "b", "test", "test.1", "1`1", "test", "test", "\\\\test",
     };
     try (Connection connection = EnvFactory.getEnv().getConnection();
         Statement statement = connection.createStatement()) {
@@ -733,7 +733,7 @@ public class IoTDBSyntaxConventionStringLiteralIT {
     };
 
     String[] res = {
-      "b", "test", "test.1", "1`1", "test", "test", "\\test",
+      "b", "test", "test.1", "1`1", "test", "test", "\\\\test",
     };
     try (Connection connection = EnvFactory.getEnv().getConnection();
         Statement statement = connection.createStatement()) {
diff --git a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java
index e2bab16409..04318babab 100644
--- a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java
+++ b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBUDTFBuiltinFunctionIT.java
@@ -201,7 +201,7 @@ public class IoTDBUDTFBuiltinFunctionIT {
         Statement statement = connection.createStatement()) {
       ResultSet resultSet =
           statement.executeQuery(
-              "select STRING_CONTAINS(s6, 's'='0'), STRING_MATCHES(s6, 'regex'='\\\\d') from root.sg.d1");
+              "select STRING_CONTAINS(s6, 's'='0'), STRING_MATCHES(s6, 'regex'='\\d') from root.sg.d1");
 
       int columnCount = resultSet.getMetaData().getColumnCount();
       assertEquals(1 + 2, columnCount);
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java b/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
index 003e0e8f6b..31861e3e10 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
@@ -84,6 +84,9 @@ public class PartialPath extends Path implements Comparable<Path>, Cloneable {
   }
 
   /**
+   * only use this method in following situations: 1. you are sure you do not want to split the
+   * path. 2. you are sure path is correct.
+   *
    * @param path path
    * @param needSplit whether to split path to nodes, needSplit can only be false.
    */
@@ -122,6 +125,10 @@ public class PartialPath extends Path implements Comparable<Path>, Cloneable {
     fullPath = String.join(TsFileConstant.PATH_SEPARATOR, nodes);
   }
 
+  /**
+   * only use this method in following situations: 1. you are sure node is allowed in syntax
+   * convention. 2. you are sure node needs not to be checked.
+   */
   public PartialPath concatNode(String node) {
     String[] newPathNodes = Arrays.copyOf(nodes, nodes.length + 1);
     newPathNodes[newPathNodes.length - 1] = node;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
index 90f3fc8952..74236f6a1c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
@@ -1195,15 +1195,17 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
 
   private String parseStringLiteral(String src) {
     if (2 <= src.length()) {
-      String unescapeString = StringEscapeUtils.unescapeJava(src.substring(1, src.length() - 1));
+      // do not unescape string
+      String unWrappedString =
+          src.substring(1, src.length() - 1).replace("\\\"", "\"").replace("\\'", "'");
       if (src.charAt(0) == '\"' && src.charAt(src.length() - 1) == '\"') {
         // replace "" with "
-        String replaced = unescapeString.replace("\"\"", "\"");
+        String replaced = unWrappedString.replace("\"\"", "\"");
         return replaced.length() == 0 ? "" : replaced;
       }
       if ((src.charAt(0) == '\'' && src.charAt(src.length() - 1) == '\'')) {
         // replace '' with '
-        String replaced = unescapeString.replace("''", "'");
+        String replaced = unWrappedString.replace("''", "'");
         return replaced.length() == 0 ? "" : replaced;
       }
     }
@@ -1220,6 +1222,23 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
     return src;
   }
 
+  private String parseStringLiteralInLikeOrRegular(String src) {
+    if (2 <= src.length()) {
+      String unescapeString = StringEscapeUtils.unescapeJava(src.substring(1, src.length() - 1));
+      if (src.charAt(0) == '\"' && src.charAt(src.length() - 1) == '\"') {
+        // replace "" with "
+        String replaced = unescapeString.replace("\"\"", "\"");
+        return replaced.length() == 0 ? "" : replaced;
+      }
+      if ((src.charAt(0) == '\'' && src.charAt(src.length() - 1) == '\'')) {
+        // replace '' with '
+        String replaced = unescapeString.replace("''", "'");
+        return replaced.length() == 0 ? "" : replaced;
+      }
+    }
+    return src;
+  }
+
   private String parseIdentifier(String src) {
     if (src.startsWith(TsFileConstant.BACK_QUOTE_STRING)
         && src.endsWith(TsFileConstant.BACK_QUOTE_STRING)) {
@@ -1656,13 +1675,13 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
   private Expression parseRegularExpression(ExpressionContext context, boolean inWithoutNull) {
     return new RegularExpression(
         parseExpression(context.unaryBeforeRegularOrLikeExpression, inWithoutNull),
-        parseStringLiteral(context.STRING_LITERAL().getText()));
+        parseStringLiteralInLikeOrRegular(context.STRING_LITERAL().getText()));
   }
 
   private Expression parseLikeExpression(ExpressionContext context, boolean inWithoutNull) {
     return new LikeExpression(
         parseExpression(context.unaryBeforeRegularOrLikeExpression, inWithoutNull),
-        parseStringLiteral(context.STRING_LITERAL().getText()));
+        parseStringLiteralInLikeOrRegular(context.STRING_LITERAL().getText()));
   }
 
   private Expression parseInExpression(ExpressionContext context, boolean inWithoutNull) {
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 954d043a62..90508716b9 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
@@ -2696,7 +2696,7 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
     }
     return new RegularExpression(
         parseExpression(context.unaryBeforeRegularOrLikeExpression, inWithoutNull),
-        parseStringLiteral(context.STRING_LITERAL().getText()));
+        parseStringLiteralInLikeOrRegular(context.STRING_LITERAL().getText()));
   }
 
   private Expression parseLikeExpression(
@@ -2708,7 +2708,7 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
     }
     return new LikeExpression(
         parseExpression(context.unaryBeforeRegularOrLikeExpression, inWithoutNull),
-        parseStringLiteral(context.STRING_LITERAL().getText()));
+        parseStringLiteralInLikeOrRegular(context.STRING_LITERAL().getText()));
   }
 
   private Expression parseInExpression(ExpressionContext context, boolean inWithoutNull) {
@@ -3000,15 +3000,17 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
 
   private String parseStringLiteral(String src) {
     if (2 <= src.length()) {
-      String unescapeString = StringEscapeUtils.unescapeJava(src.substring(1, src.length() - 1));
+      // do not unescape string
+      String unWrappedString =
+          src.substring(1, src.length() - 1).replace("\\\"", "\"").replace("\\'", "'");
       if (src.charAt(0) == '\"' && src.charAt(src.length() - 1) == '\"') {
         // replace "" with "
-        String replaced = unescapeString.replace("\"\"", "\"");
+        String replaced = unWrappedString.replace("\"\"", "\"");
         return replaced.length() == 0 ? "" : replaced;
       }
       if ((src.charAt(0) == '\'' && src.charAt(src.length() - 1) == '\'')) {
         // replace '' with '
-        String replaced = unescapeString.replace("''", "'");
+        String replaced = unWrappedString.replace("''", "'");
         return replaced.length() == 0 ? "" : replaced;
       }
     }
@@ -3025,6 +3027,23 @@ public class IoTDBSqlVisitor extends IoTDBSqlParserBaseVisitor<Operator> {
     return src;
   }
 
+  private String parseStringLiteralInLikeOrRegular(String src) {
+    if (2 <= src.length()) {
+      String unescapeString = StringEscapeUtils.unescapeJava(src.substring(1, src.length() - 1));
+      if (src.charAt(0) == '\"' && src.charAt(src.length() - 1) == '\"') {
+        // replace "" with "
+        String replaced = unescapeString.replace("\"\"", "\"");
+        return replaced.length() == 0 ? "" : replaced;
+      }
+      if ((src.charAt(0) == '\'' && src.charAt(src.length() - 1) == '\'')) {
+        // replace '' with '
+        String replaced = unescapeString.replace("''", "'");
+        return replaced.length() == 0 ? "" : replaced;
+      }
+    }
+    return src;
+  }
+
   private String parseIdentifier(String src) {
     if (src.startsWith(TsFileConstant.BACK_QUOTE_STRING)
         && src.endsWith(TsFileConstant.BACK_QUOTE_STRING)) {