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)) {