lincoln-lil commented on code in PR #25225: URL: https://github.com/apache/flink/pull/25225#discussion_r1730585595
########## flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/ScalarFunctionsTest.scala: ########## @@ -387,55 +387,91 @@ class ScalarFunctionsTest extends ScalarTypesTestBase { @Test def testLike(): Unit = { + // true testAllApis('f0.like("Th_s%"), "f0 LIKE 'Th_s%'", "TRUE") - testAllApis('f0.like("%is a%"), "f0 LIKE '%is a%'", "TRUE") - - testSqlApi("'abcxxxdef' LIKE 'abcx%'", "TRUE") - testSqlApi("'abcxxxdef' LIKE '%%def'", "TRUE") - testSqlApi("'abcxxxdef' LIKE 'abcxxxdef'", "TRUE") - testSqlApi("'abcxxxdef' LIKE '%xdef'", "TRUE") - testSqlApi("'abcxxxdef' LIKE 'abc%def%'", "TRUE") - testSqlApi("'abcxxxdef' LIKE '%abc%def'", "TRUE") - testSqlApi("'abcxxxdef' LIKE '%abc%def%'", "TRUE") - testSqlApi("'abcxxxdef' LIKE 'abc%def'", "TRUE") + testAllApis("abcxxxdef".like("abcx%"), "'abcxxxdef' LIKE 'abcx%'", "TRUE") + testAllApis("abcxxxdef".like("%%def"), "'abcxxxdef' LIKE '%%def'", "TRUE") + testAllApis("abcxxxdef".like("abcxxxdef"), "'abcxxxdef' LIKE 'abcxxxdef'", "TRUE") + testAllApis("abcxxxdef".like("%xdef"), "'abcxxxdef' LIKE '%xdef'", "TRUE") + testAllApis("abcxxxdef".like("abc%def%"), "'abcxxxdef' LIKE 'abc%def%'", "TRUE") + testAllApis("abcxxxdef".like("%abc%def"), "'abcxxxdef' LIKE '%abc%def'", "TRUE") + testAllApis("abcxxxdef".like("%abc%def%"), "'abcxxxdef' LIKE '%abc%def%'", "TRUE") + testAllApis("abcxxxdef".like("abc%def"), "'abcxxxdef' LIKE 'abc%def'", "TRUE") // false - testSqlApi("'abcxxxdef' LIKE 'abdxxxdef'", "FALSE") - testSqlApi("'abcxxxdef' LIKE '%xqef'", "FALSE") - testSqlApi("'abcxxxdef' LIKE 'abc%qef%'", "FALSE") - testSqlApi("'abcxxxdef' LIKE '%abc%qef'", "FALSE") - testSqlApi("'abcxxxdef' LIKE '%abc%qef%'", "FALSE") - testSqlApi("'abcxxxdef' LIKE 'abc%qef'", "FALSE") + testAllApis("abcxxxdef".like("abdxxxdef"), "'abcxxxdef' LIKE 'abdxxxdef'", "FALSE") + testAllApis("abcxxxdef".like("%xqef"), "'abcxxxdef' LIKE '%xqef'", "FALSE") + testAllApis("abcxxxdef".like("abc%qef%"), "'abcxxxdef' LIKE 'abc%qef%'", "FALSE") + testAllApis("abcxxxdef".like("%abc%qef"), "'abcxxxdef' LIKE '%abc%qef'", "FALSE") + testAllApis("abcxxxdef".like("%abc%qef%"), "'abcxxxdef' LIKE '%abc%qef%'", "FALSE") + testAllApis("abcxxxdef".like("abc%qef"), "'abcxxxdef' LIKE 'abc%qef'", "FALSE") + + // reported in FLINK-36100 + testAllApis("TE_ST".like("%E_S%"), "'TE_ST' LIKE '%E_S%'", "TRUE") + testAllApis("TE-ST".like("%E_S%"), "'TE-ST' LIKE '%E_S%'", "TRUE") + testAllApis("TE_ST".like("%E\\_S%"), "'TE_ST' LIKE '%E\\_S%'", "TRUE") + testAllApis("TE-ST".like("%E\\_S%"), "'TE-ST' LIKE '%E\\_S%'", "FALSE") } @Test def testNotLike(): Unit = { testAllApis(!'f0.like("Th_s%"), "f0 NOT LIKE 'Th_s%'", "FALSE") - testAllApis(!'f0.like("%is a%"), "f0 NOT LIKE '%is a%'", "FALSE") + + // reported in FLINK-36100 + testSqlApi("'TE_ST' NOT LIKE '%E_S%'", "FALSE") + testSqlApi("'TE-ST' NOT LIKE '%E_S%'", "FALSE") + testSqlApi("'TE_ST' NOT LIKE '%E\\_S%'", "FALSE") + testSqlApi("'TE-ST' NOT LIKE '%E\\_S%'", "TRUE") } @Test def testLikeWithEscape(): Unit = { Review Comment: Add cases with invalid escape chars ########## flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/functions/SqlLikeUtils.java: ########## @@ -108,15 +108,18 @@ static String sqlToRegexLike(String sqlPattern, char escapeChar) { final StringBuilder javaPattern = new StringBuilder(len + len); for (i = 0; i < len; i++) { char c = sqlPattern.charAt(i); - if (JAVA_REGEX_SPECIALS.indexOf(c) >= 0) { - javaPattern.append('\\'); - } if (c == escapeChar) { if (i == (sqlPattern.length() - 1)) { throw invalidEscapeSequence(sqlPattern, i); } char nextChar = sqlPattern.charAt(i + 1); - if ((nextChar == '_') || (nextChar == '%') || (nextChar == escapeChar)) { + if ((nextChar == '_') || (nextChar == '%')) { Review Comment: We'd better also add some tests into `FlinkSqlLikeUtilsTest` to cover these changes. ########## docs/data/sql_functions.yml: ########## @@ -49,10 +49,10 @@ comparison: - sql: value1 NOT BETWEEN [ ASYMMETRIC | SYMMETRIC ] value2 AND value3 description: By default (or with the ASYMMETRIC keyword), returns TRUE if value1 is less than value2 or greater than value3. With the SYMMETRIC keyword, returns TRUE if value1 is not inclusively between value2 and value3. When either value2 or value3 is NULL, returns TRUE or UNKNOWN. E.g., 12 NOT BETWEEN 15 AND 12 returns TRUE; 12 NOT BETWEEN SYMMETRIC 15 AND 12 returns FALSE; 12 NOT BETWEEN NULL AND 15 returns UNKNOWN; 12 NOT BETWEEN 15 AND NULL returns TRUE; 12 NOT BETWEEN SYMMETRIC 12 AND NULL returns UNKNOWN. - sql: string1 LIKE string2 [ ESCAPE char ] - table: string1.like(string2) - description: Returns TRUE if string1 matches pattern string2; returns UNKNOWN if string1 or string2 is NULL. An escape character can be defined if necessary. The escape character has not been supported yet. + table: string1.like(string2[, char]) + description: Returns TRUE if string1 matches pattern string2; returns UNKNOWN if string1 or string2 is NULL. An escape character can be defined if necessary, '\' by default. Review Comment: Clarify the length limit of escape characters ########## docs/data/sql_functions_zh.yml: ########## @@ -69,14 +69,14 @@ comparison: `12 NOT BETWEEN 15 AND NULL` 返回 `TRUE`; `12 NOT BETWEEN SYMMETRIC 12 AND NULL` 返回 `UNKNOWN`。 - sql: string1 LIKE string2 [ ESCAPE char ] - table: string1.like(string2) + table: string1.like(string2[, char]) description: | 如果 string1 匹配 string2 返回 `TRUE`;如果 string1 或 string2 为 `NULL` 返回 `UNKNOWN`。 - 如果需要可以定义转义字符。尚不支持转义字符。 + 如果需要可以定义转义字符,默认为 '\'。 Review Comment: ditto -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@flink.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org