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

   ### What changes were proposed in this pull request?
   
   `StringSplit` (`split`) now keeps the last regex and its compiled `Pattern` 
instead of compiling the regex on every row. It uses the same `lastRegex` / 
`pattern` cache that `RegExpReplace` and `RegExpExtractBase` already have.
   
   - `UTF8String`: new `split(Pattern, int)` and `splitLegacyTruncate(Pattern, 
int)` overloads.
     - An empty pattern delegates to the existing empty-regex branches 
(SPARK-49968), so that logic isn't duplicated.
     - Otherwise they split with the compiled pattern. The exception is a regex 
that qualifies for `String.split`'s single-character `indexOf` fast path, on a 
pattern with no flags. That case still goes through `String.split`, because the 
fast path beats matching even a pre-compiled `Pattern`.
     - `splitsWithoutRegex` mirrors the JDK's fast-path check. It only picks 
between two calls that return the same result, since outside the fast path 
`String.split` is `Pattern.compile(regex).split(this, limit)`.
   - `StringSplit`: both the interpreted and the codegen paths compile 
`CollationSupport.collationAwareRegex(regex, ...)` only when the regex value 
changes. They then call the new overloads.
     - The regex is cloned before it is cached, because the input may point 
into a reused row buffer.
     - `stateful` is now `true`, as for the other caching regex expressions.
   - `StringFunctionsBenchmark`: adds three `split` cases.
   
   I didn't reuse `RegExpUtils.getPatternAndLastRegex` / `initLastPatternCode`. 
They compile with collation flags and wrap `PatternSyntaxException` in 
`INVALID_PARAMETER_VALUE.PATTERN`. That would change two things:
   - the error `split` raises for an invalid regex;
   - the result for UTF8_LCASE + `spark.sql.legacy.truncateForEmptyRegexSplit` 
+ an empty regex. Today the `(?ui)` prefix makes that regex non-empty, so it 
takes the regex path.
   
   Compiling the exact string `String.split` compiles today keeps both 
unchanged.
   
   ### Why are the changes needed?
   
   `UTF8String.split(UTF8String, int)` decodes the regex and calls 
`String.split`, which runs `Pattern.compile(regex)` on every call unless the 
regex is a single literal character. As a result, these compile a new `Pattern` 
for every row even though the regex is a literal:
   - `split(s, '[,;]')`
   - `split(s, '\\s+')`
   - `split(s, '|')`
   - any UTF8_LCASE `split`, whose regex gets a `(?ui)` prefix
   
   Local `StringFunctionsBenchmark` numbers, 1M rows like `123-246`, ns/row. 
The JDK 25 numbers come from before/after runs interleaved on the same machine:
   
   | Case | JDK 17 before | JDK 17 after | JDK 25 before | JDK 25 after |
   |---|---|---|---|---|
   | `split(subject, '[-]')` | 424 | 346 | 366 | 266 |
   | `split(subject COLLATE UTF8_LCASE, '-')` | 477 | 353 | 395 | 281 |
   | `split(subject, '-')` (single-char fast path) | 258 | 262 | 195 | 196 |
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. Results are unchanged. An invalid regex raises the same exception as 
before, at the same point (the first row with non-null inputs).
   
   ### How was this patch tested?
   
   New tests:
   - `UTF8StringSuite.splitWithCompiledPattern`: checks that `split(Pattern, 
int)` / `splitLegacyTruncate(Pattern, int)` match the `UTF8String` overloads 
across fast-path and real-regex patterns, empty patterns and inputs, and 
several limits. It also checks that a pattern compiled with `CASE_INSENSITIVE` 
skips the fast path.
   - `RegexpExpressionsSuite` "split refreshes its cached pattern when the 
regex changes": the regex changes across rows that share a reused `UnsafeRow` 
buffer, tested both interpreted and with codegen. It fails if the cached regex 
isn't cloned.
   
   Existing tests:
   - `RegexpExpressionsSuite` `SPLIT`
   - `CollationRegexpExpressionsSuite`
   - the split tests in `StringFunctionsSuite`, `CollationSQLRegexpSuite` and 
`CharVarcharTestSuite`
   - `SQLQueryTestSuite` `collations-string-functions` (no golden-file changes)
   
   The benchmark result files will be regenerated on GitHub Actions (JDK 
17/21/25).
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Code (Claude Opus 5.5)
   
   This pull request and its description were written by Isaac.
   


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