diff --git a/common/src/main/java/org/opensearch/sql/common/utils/StringUtils.java b/common/src/main/java/org/opensearch/sql/common/utils/StringUtils.java index c81f56ef634..4d26c6190e9 100644 --- a/common/src/main/java/org/opensearch/sql/common/utils/StringUtils.java +++ b/common/src/main/java/org/opensearch/sql/common/utils/StringUtils.java @@ -63,8 +63,11 @@ public static String unquoteText(String text) { for (int chIndex = 1; chIndex < text.length() - 1; chIndex++) { currentChar = text.charAt(chIndex); nextChar = text.charAt(chIndex + 1); - if (currentChar == enclosingQuote && nextChar == currentChar) { + + if ((currentChar == '\\' && (nextChar == '"' || nextChar == '\\' || nextChar == '\'')) + || (currentChar == nextChar && currentChar == enclosingQuote)) { chIndex++; + currentChar = nextChar; } textSB.append(currentChar); } diff --git a/docs/user/dql/expressions.rst b/docs/user/dql/expressions.rst index 4816121be2c..460fa47c181 100644 --- a/docs/user/dql/expressions.rst +++ b/docs/user/dql/expressions.rst @@ -46,7 +46,7 @@ Here is an example for different type of literals:: +---------+---------+---------+---------+--------+---------+---------+-----------+----------+ | "Hello" | 'Hello' | "It""s" | 'It''s' | "It's" | '"Its"' | 'It\'s' | 'It\\\'s' | "\I\t\s" | |---------+---------+---------+---------+--------+---------+---------+-----------+----------| - | Hello | Hello | It"s | It's | It's | "Its" | It\'s | It\\\'s | \I\t\s | + | Hello | Hello | It"s | It's | It's | "Its" | It's | It\'s | \I\t\s | +---------+---------+---------+---------+--------+---------+---------+-----------+----------+ diff --git a/integ-test/src/test/java/org/opensearch/sql/ppl/SearchCommandIT.java b/integ-test/src/test/java/org/opensearch/sql/ppl/SearchCommandIT.java index 4620ca586c0..b251e5bc694 100644 --- a/integ-test/src/test/java/org/opensearch/sql/ppl/SearchCommandIT.java +++ b/integ-test/src/test/java/org/opensearch/sql/ppl/SearchCommandIT.java @@ -523,7 +523,7 @@ public void testWildcardEscaping() throws IOException { executeQuery( String.format( "search source=%s" - + " `attributes.error.type`=\\\"C:\\\\\\\\Users\\\\\\\\admin\\\"" + + " `attributes.error.type`=\\\"C:\\\\\\\\\\\\\\\\Users\\\\\\\\\\\\\\\\admin\\\"" + " | sort time | fields attributes.error.type", TEST_INDEX_OTEL_LOGS)); verifyDataRows(backslashSearch, rows("C:\\Users\\admin")); diff --git a/integ-test/src/test/java/org/opensearch/sql/sql/WildcardQueryIT.java b/integ-test/src/test/java/org/opensearch/sql/sql/WildcardQueryIT.java index c6e43010d90..8123f887f23 100644 --- a/integ-test/src/test/java/org/opensearch/sql/sql/WildcardQueryIT.java +++ b/integ-test/src/test/java/org/opensearch/sql/sql/WildcardQueryIT.java @@ -191,7 +191,7 @@ public void test_backslash_wildcard() throws IOException { String query = "SELECT KeywordBody FROM " + TEST_INDEX_WILDCARD - + " WHERE wildcard_query(KeywordBody, '*\\\\\\\\\\\\_')"; + + " WHERE wildcard_query(KeywordBody, '*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_')"; JSONObject result = executeJdbcRequest(query); verifyDataRows(result, rows("test backslash wildcard \\_")); } diff --git a/ppl/src/test/java/org/opensearch/sql/ppl/calcite/CalcitePPLStringFunctionTest.java b/ppl/src/test/java/org/opensearch/sql/ppl/calcite/CalcitePPLStringFunctionTest.java index d1c11aec0af..1e97052dea0 100644 --- a/ppl/src/test/java/org/opensearch/sql/ppl/calcite/CalcitePPLStringFunctionTest.java +++ b/ppl/src/test/java/org/opensearch/sql/ppl/calcite/CalcitePPLStringFunctionTest.java @@ -285,12 +285,12 @@ public void testReplaceWithRegexPattern() { String ppl = "source=EMP | eval no_digits = replace(JOB, '\\\\d+', '') | fields JOB, no_digits"; RelNode root = getRelNode(ppl); String expectedLogical = - "LogicalProject(JOB=[$2], no_digits=[REGEXP_REPLACE($2, '\\\\d+':VARCHAR, '':VARCHAR)])\n" + "LogicalProject(JOB=[$2], no_digits=[REGEXP_REPLACE($2, '\\d+':VARCHAR, '':VARCHAR)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; verifyLogical(root, expectedLogical); String expectedSparkSql = - "SELECT `JOB`, REGEXP_REPLACE(`JOB`, '\\\\d+', '') `no_digits`\n" + "FROM `scott`.`EMP`"; + "SELECT `JOB`, REGEXP_REPLACE(`JOB`, '\\d+', '') `no_digits`\n" + "FROM `scott`.`EMP`"; verifyPPLToSparkSQL(root, expectedSparkSql); } @@ -303,12 +303,12 @@ public void testReplaceWithRegexCaptureGroups() { RelNode root = getRelNode(ppl); String expectedLogical = "LogicalProject(ENAME=[$1], swapped=[REGEXP_REPLACE($1, '^(.)(.)':VARCHAR," - + " '\\$2\\$1')])\n" + + " '$2$1')])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; verifyLogical(root, expectedLogical); String expectedSparkSql = - "SELECT `ENAME`, REGEXP_REPLACE(`ENAME`, '^(.)(.)', '\\$2\\$1') `swapped`\n" + "SELECT `ENAME`, REGEXP_REPLACE(`ENAME`, '^(.)(.)', '$2$1') `swapped`\n" + "FROM `scott`.`EMP`"; verifyPPLToSparkSQL(root, expectedSparkSql); }