Skip to content

fix: Avoid mistaken ILike to string equality optimization #15836

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1606,8 +1606,9 @@ impl<S: SimplifyInfo> TreeNodeRewriter for Simplifier<'_, S> {
}))
}
Some(pattern_str)
if !pattern_str
.contains(['%', '_', escape_char].as_ref()) =>
if !like.case_insensitive
&& !pattern_str
.contains(['%', '_', escape_char].as_ref()) =>
{
// If the pattern does not contain any wildcards, we can simplify the like expression to an equality expression
// TODO: handle escape characters
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like we have completed the TODO as well -- can yoy remove this comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that comment is referring to parsing escape characters and performing the optimization on strings with character escapes too.

Expand Down Expand Up @@ -4102,6 +4103,11 @@ mod tests {
assert_eq!(simplify(expr), col("c1").like(lit("a_")));
let expr = col("c1").not_like(lit("a_"));
assert_eq!(simplify(expr), col("c1").not_like(lit("a_")));

let expr = col("c1").ilike(lit("a"));
assert_eq!(simplify(expr), col("c1").ilike(lit("a")));
let expr = col("c1").not_ilike(lit("a"));
assert_eq!(simplify(expr), col("c1").not_ilike(lit("a")));
}

#[test]
Expand Down
6 changes: 6 additions & 0 deletions datafusion/sqllogictest/test_files/strings.slt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ p1
p1e1
p1m1e1

query T rowsort
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case anyone is curious, without the fix this test fails like this:

Completed 1 test files in 0 seconds                                                                                                                                                                                             External error: query result mismatch:
[SQL] SELECT s FROM test WHERE s ILIKE 'p1';
[Diff] (-expected|+actual)
-   P1
    p1
at test_files/strings.slt:118

SELECT s FROM test WHERE s ILIKE 'p1';
----
P1
p1

# NOT ILIKE
query T rowsort
SELECT s FROM test WHERE s NOT ILIKE 'p1%';
Expand Down