github-actions[bot] commented on code in PR #68133:
URL: https://github.com/apache/doris/pull/68133#discussion_r4035564829


##########
be/test/exprs/function/function_like_test.cpp:
##########
@@ -144,6 +144,84 @@ TEST(FunctionLikeTest, like) {
             func_name, const_pattern_input_types, data_set));
 }
 
+TEST(FunctionLikeTest, like_matches_whole_value) {
+    std::string func_name = "like";
+
+    DataSet data_set = {
+            // A trailing newline belongs to the value, so a pattern that is 
anchored at the
+            // tail must not match across it.
+            {{std::string("acb"), std::string("a_b")}, uint8_t(1)},
+            {{std::string("acb\n"), std::string("a_b")}, uint8_t(0)},
+            {{std::string("acb\r\n"), std::string("a_b")}, uint8_t(0)},
+            {{std::string("acb\n\n"), std::string("a_b")}, uint8_t(0)},
+            {{std::string("acbx"), std::string("a_b")}, uint8_t(0)},
+            {{std::string("\nacb"), std::string("a_b")}, uint8_t(0)},
+            {{std::string("abc"), std::string("a%c")}, uint8_t(1)},
+            {{std::string("abc\n"), std::string("a%c")}, uint8_t(0)},
+            {{std::string("abc\n"), std::string("%b%c")}, uint8_t(0)},
+            // The newline is an ordinary character for '_' and '%'.
+            {{std::string("a\nb"), std::string("a_b")}, uint8_t(1)},
+            {{std::string("a\nb"), std::string("a%b")}, uint8_t(1)},
+            {{std::string("acb\n"), std::string("a_b_")}, uint8_t(1)},
+            {{std::string("acb\n"), std::string("a_b%")}, uint8_t(1)},
+            {{std::string("abc\n"), std::string("a_c%")}, uint8_t(1)},
+            // '_' stands for one character, not for one byte.
+            {{std::string("a中b"), std::string("a_b")}, uint8_t(1)},
+            {{std::string("a中b\n"), std::string("a_b")}, uint8_t(0)},
+            // An empty pattern only matches an empty value.
+            {{std::string(""), std::string("")}, uint8_t(1)},
+            {{std::string("\n"), std::string("")}, uint8_t(0)},
+            // The shortcut paths and the regex path must agree on the same 
value.
+            {{std::string("acb\n"), std::string("acb")}, uint8_t(0)},
+            {{std::string("abc\n"), std::string("%c")}, uint8_t(0)},
+            {{std::string("abc\n"), std::string("a%")}, uint8_t(1)},
+            // A pattern open at the tail must not make the engines walk the 
rest of the value:
+            // `.*` only matches valid UTF-8, so anchoring it with `\z` would 
make RE2 reject a
+            // value whose tail is not valid UTF-8 while Hyperscan still 
accepts it.
+            {{std::string("acb\xff", 4), std::string("a_b%")}, uint8_t(1)},

Review Comment:
   [P2] Avoid asserting undefined Hyperscan UTF-8 behavior
   
   `check_function_all_arg_comb` includes constant-pattern runs, and `a_b%` 
bypasses the LIKE fast paths because of `_`. That makes 
`construct_like_const_state` compile `^a.b` with `HS_FLAG_UTF8` and pass this 
four-byte `acb\xff` buffer to `hs_scan`. [Hyperscan's 
API](https://intel.github.io/hyperscan/dev-reference/api_constants.html#c.HS_FLAG_UTF8)
 explicitly says that scanning invalid UTF-8 with this flag has undefined 
results, so this expected `1` can vary across engine versions or architectures 
and cannot prove Hyperscan/RE2 equivalence. Please route invalid input through 
a matcher with defined byte semantics (or otherwise keep it out of the UTF-8 
Hyperscan path) before asserting this result.



##########
be/src/exprs/function/like.cpp:
##########
@@ -809,6 +810,10 @@ void FunctionLike::convert_like_pattern(const 
LikeSearchState* state, const std:
         }
 
         if (c == '%') {
+            if (i + 1 == pattern.size()) {

Review Comment:
   [P2] Preserve wildcard parity with an explicit backslash escape
   
   This leaves a supported trailing-wildcard form outside the fix. With a 
one-byte backslash as the explicit escape, pattern bytes `[0x5c, 0x5c, 0x25]` 
mean a literal backslash followed by wildcard `%`, but 
`replace_pattern_by_escape` first collapses the pair to `[0x5c, 0x25]`. 
Downstream fast-path recognition can then classify `%` as a literal, and the 
regex fallback likewise consumes it as escaped, so the pattern no longer has an 
open literal-backslash prefix. The normalization bug predates this branch, but 
both constant and nonconstant three-argument LIKE paths remain incorrect. 
Please preserve the original default-backslash representation (or otherwise 
retain escape parity), and add coverage showing that a literal-backslash prefix 
followed by `%` remains open.



##########
be/src/exprs/function/like.cpp:
##########
@@ -809,6 +810,10 @@ void FunctionLike::convert_like_pattern(const 
LikeSearchState* state, const std:
         }
 
         if (c == '%') {
+            if (i + 1 == pattern.size()) {
+                // a trailing `%` matches anything, and so does appending 
nothing
+                return;
+            }
             re_pattern->append(".*");

Review Comment:
   [P2] Handle invalid bytes for interior percent wildcards too
   
   The new invalid-input case establishes that SQL `%` must be able to absorb 
bytes that are not valid UTF-8, but this change makes only the terminal 
wildcard byte-safe. For example, `a%b` still becomes `^a.*b\z`; the nonconstant 
path runs that through UTF-8 RE2, where `.` matches a code point and cannot 
traverse the `0xff` in bytes `[0x61, 0xff, 0x62]`, so it returns false. The 
constant-pattern Hyperscan path is undefined for the same invalid input, 
creating an additional path split. Although the interior case predates this 
hunk, it leaves the byte-semantics contract introduced here incomplete. Please 
give every `%` defined byte-safe semantics (or validate/route invalid input 
consistently), and cover constant, nonconstant, pushdown, and NOT LIKE forms 
with an invalid byte between required literals. [RE2 syntax 
reference](https://github.com/google/re2/wiki/Syntax)



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to