david-mollitor-db opened a new pull request, #58644:
URL: https://github.com/apache/spark/pull/58644

   ### What changes were proposed in this pull request?
   
   `LikeSimplification` gives up on a pattern the moment it contains the escape 
character
   (`if (pattern.contains(escapeChar)) None`), so escaped-literal patterns stay 
a full per-row
   regex even when they are trivially sargable once the escapes are decoded:
   
   ```
   col LIKE 'ma\%ca'           ==>  col = 'ma%ca'
   col LIKE 'abc\%def%'        ==>  StartsWith(col, 'abc%def')
   col LIKE '%mn\%'            ==>  EndsWith(col, 'mn%')
   col LIKE 'abbc' ESCAPE 'b'  ==>  col = 'abc'
   ```
   
   This PR decodes valid escape sequences and applies the rule's existing shape 
simplifications
   (`EqualTo` / `StartsWith` / `EndsWith` / `Contains` / 
`StartsWith`+`EndsWith`) to the decoded
   literals.
   
   How it works:
   - **Fast path (unchanged):** a quick `pattern.contains(escapeChar)` scan — 
when the escape
     character is absent, the existing five regexes run exactly as before, so 
the common case pays
     nothing for the decode logic.
   - **Guard:** otherwise, if the escape character is itself `%` or `_` (a 
pathological
     `ESCAPE '%'` / `ESCAPE '_'`), skip — unchanged behavior. This guard 
follows the fast-path scan
     on purpose: an `ESCAPE '%'` pattern that contains no `%` is still 
simplifiable via the fast
     path.
   - **Decode:** otherwise, walk the pattern turning `\%` / `\_` / `\\` into 
literal characters,
     treating unescaped `%`/`_` as wildcards, and classify the decoded shape.
   
   An unescaped `_` wildcard and `LikeAll`/`LikeAny` shapes beyond what 
`simplifyLike` already
   covers remain out of scope.
   
   ### Why are the changes needed?
   
   Escaped-literal patterns become sargable: the resulting 
`EqualTo`/`StartsWith`/etc. push down to
   data sources (e.g. Parquet prunes on `StringStartsWith`) and short-circuit 
the per-row regex,
   instead of always running the regex and pushing nothing.
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. Query results are identical, and error cases still error; this is a 
performance improvement.
   
   A valid-escape pattern's decoded literal is exactly the string the `LIKE` 
matches, so the rewrite
   is behavior-preserving. An escape character followed by anything other than 
`%`, `_`, or itself,
   or a trailing escape character, makes `LIKE` throw at runtime 
(`INVALID_FORMAT.ESC_IN_THE_MIDDLE`
   / `ESC_AT_THE_END`); the rule returns `None` for these, so the `Like` is 
kept and throws exactly
   as today. Every shape fully replaces the `Like` (no residual), so the 
rewrite is idempotent.
   
   ### How was this patch tested?
   
   `LikeSimplificationSuite`: updated the existing escape tests (they 
previously asserted the
   pattern was skipped and now assert the simplified form, including the 
`LikeAll`/`LikeAny`
   multi-pattern tests whose escaped entries now fold in), and added tests for 
valid-escape
   simplification across all shapes and for the still-skipped cases (invalid 
escape, trailing
   escape, `ESCAPE '%'`/`ESCAPE '_'`, and an unescaped `_`).
   `build/sbt 'catalyst/testOnly *LikeSimplificationSuite'` passes; scalastyle 
clean.
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Opus 4.8
   


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