Implement Spark-compatible `rlike` / `regexp` / `regexp_like`
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 33/100
Direzione di ricerca
Start by reading datafusion/functions/src/regex/regexplike.rs and the existing crates/spark/src/function/string/like.rs to see how a Spark-compatible predicate is wired with #[user_doc] and return_field_from_args. The bulk of the work is the shared Java-regex compatibility helper in the proposed crates/spark/src/function/string/regex_utils.rs; the predicate module is currently empty, so decide where it lives before writing. Done looks like rlike/regexp/regexp_like registered with NULL propagation, the INVALID_PARAMETER_VALUE.PATTERN error and not_impl_err! for out-of-subset patterns, verified by a new crates/sqllogictest/test_files/predicate/rlike.slt.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Part of #174 and apache/datafusion-comet#7300.
What the function does
rlike(str, regexp) returns true if the Java regular expression regexp matches anywhere in str (Spark calls Pattern.matcher(str).find(0), so the match is unanchored), false otherwise. regexp and regexp_like are aliases registered since 3.2.0; str RLIKE regexp and str REGEXP regexp are the operator forms. rlike has been available since 1.0.0.
Both arguments are implicitly cast to STRING (ImplicitCastInputTypes). Result is BOOLEAN; NULL if either argument is NULL (nullIntolerant). There is no flags argument. In 4.0+ the inputs are StringTypeBinaryLcase / StringTypeWithCollation: only UTF8_BINARY and UTF8_LCASE collations are accepted, and UTF8_LCASE compiles the pattern with CASE_INSENSITIVE | UNICODE_CASE.
Examples
SELECT regexp_like('1a 2b 14m', '\\d+b');
-- true
SELECT regexp('1a 2b 14m', '[a-z]+b');
-- false
SELECT rlike('%SystemDrive%\\Users\\John', '%SystemDrive%\\\\Users.*');
-- true
SELECT rlike('%SystemDrive%\\Users\\John', r'%SystemDrive%\\Users.*');
-- true
SET spark.sql.parser.escapedStringLiterals=true;
SELECT rlike('%SystemDrive%\Users\John', '%SystemDrive%\\Users.*');
-- true
SELECT rlike('abbbbc', '**');
-- error INVALID_PARAMETER_VALUE.PATTERN
Edge cases to test
- NULL
str, NULLregexp, both NULL, for literal and column patterns: all return NULL. - Empty pattern:
rlike(x, '')is true for any non-NULLx, including''. - Invalid pattern: error
INVALID_PARAMETER_VALUE.PATTERN(SQLSTATE 22023), messageThe value of parameter(s) `regexp` in `rlike` is invalid: '<pattern>'.(thefunctionNameparameter is the alias used, e.g.`regexp_like`). Raised for both literal and per-row patterns. - Non-literal (column) patterns: Spark compiles per row. Test a column with mixed valid patterns, and one invalid pattern in a later row.
- Anchoring is not implicit:
rlike('afofo', '^fo')is false,rlike('afofo', 'fo')is true (RegexpExpressionsSuite).rlike('fo\no', '^fo\no$')is true. spark.sql.parser.escapedStringLiterals(default false) only changes how the SQL parser unescapes the literal before the function sees it; the kernel receives the final pattern string. Note that DataFusion's SQL parser keeps backslashes literal in'...', so Spark'\\d+'is DataFusion'\d+'in.sltfiles.- Java vs Rust
regexdivergences (each needs a test that either matches Spark or is rejected):- Lookaround, backreferences, atomic groups, possessive quantifiers: Java accepts, Rust fails to compile.
(?=[^ ]*[a-z])(?=[^ ]*[0-9])[^ ]+,(a)\1,(?>a),a*+. \d,\w,\sare ASCII-only in Java and Unicode in Rust:rlike('\u0663', '\\d')(ARABIC-INDIC DIGIT THREE) is false in Spark..excludes\r,\u0085,\u2028,\u2029in Java but only\nin Rust:rlike('\r', '^.$')is false in Spark.$without(?m)also matches before a final line terminator in Java:rlike('abc\n', 'abc$')is true in Spark, false in Rust.(?i)is ASCII-only in Java unless(?u)is also set; Rust folds Unicode, sorlike('\u212A', '(?i)k')(U+212A KELVIN SIGN) is false in Spark and true in Rust.- Flag letters differ: Java
UisUNICODE_CHARACTER_CLASSbut RustUswaps greediness; JavauisUNICODE_CASE, Rustutoggles Unicode mode; Javad(UNIX_LINES) is unknown to Rust. \p{Alpha},\p{Lower}etc. are ASCII POSIX classes in Java but Unicode properties in Rust.[[:alpha:]]is an ASCII class in Rust but a nested class of the characters:alphin Java.- Syntax only Rust accepts:
(?P<n>...),\</\>,\b{start}, class operators--and~~. Syntax only Java accepts:\Q...\E,\h,\R,\X,\G,\Z,\0nnoctal,\cX.
- Lookaround, backreferences, atomic groups, possessive quantifiers: Java accepts, Rust fails to compile.
- Unicode input: multi-byte and supplementary characters such as an emoji (U+1F600): Java's
.matches the whole surrogate pair and Rust's.matches the whole code point, sorlike('😀', '^.$')should be true on both sides; add a test to confirm. UTF8_LCASEcollation (4.0+):rlike('ABC' COLLATE UTF8_LCASE, 'b')matches case-insensitively.
Differences across Spark versions
- 4.0: collation-aware inputs and regex flags; result otherwise unchanged.
- 4.2: adds an
expensiveheuristic for planning (no semantic change). - Error condition for invalid patterns is
INVALID_PARAMETER_VALUE.PATTERNin all of 3.4 through 4.2.
Implementation notes
- Spark:
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/regexpExpressions.scala,RLike(base classStringRegexExpression). Grouppredicate_funcs. - DataFusion core has
regexp_like(str, regexp[, flags])(datafusion/functions/src/regex/regexplike.rs) and the~operator. Both use Rustregexsyntax and semantics and accept a flags argument Spark does not have. Wrapping them unchanged would silently differ from Spark for the cases above. - Recommended approach: a shared Java-regex compatibility helper (new module, e.g.
crates/spark/src/function/string/regex_utils.rs, reused byregexp_replace,regexp_extract_all,regexp_count,regexp_substr,regexp_instr,split). It parses the pattern (for example withregex-syntax's AST parser) and accepts it only if every construct is in a verified-compatible subset, translating where needed (e.g.\dto[0-9],.to[^\n\r\u0085\u2028\u2029]). Patterns outside the subset should return a distinct "unsupported pattern" error (not_impl_err!), not a silent result and notINVALID_PARAMETER_VALUE.PATTERN, so that callers can fall back. For literal patterns, do this check at planning time (return_field_from_argsseesscalar_arguments) so engines like Comet can decline before execution. - Cache the compiled regex for scalar patterns; cache the last pattern for column patterns.
regexis not a dependency ofcrates/sparkyet. The function belongs in thepredicatemodule (currently empty), orstringnext tolike.rs/ilike.rs.- Tests: add
crates/sqllogictest/test_files/predicate/rlike.slt(cover all three names) and document with#[user_doc], listing the supported subset.
This issue was generated by an LLM (Claude) from the Apache Spark source code and tests. Examples come from Spark's ExpressionDescription examples, test suites and .sql.out golden files, but please verify them against Spark before relying on them.
- Lingua principale
- Rust
- Stelle
- 7
- Fork
- 15
- Merge medio
- 16h 43m
- PR unite (30g)
- 26
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di apache/datafusion-spark
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
apache/datafusion-spark#287 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
apache/datafusion-spark#266 ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug] make_dt_interval returns NULL for more than about 1.49 million days, Spark returns the intervalForse già presa @Subodh-17 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
apache/datafusion-spark#109 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 5/5 Più di una settimana Idoneità per principianti 18/100
apache/datafusion-spark#299 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
apache/datafusion-spark#298 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di apache/datafusion-spark
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
storytold/photocraft#15232 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
suhina-daw/suhina-daw#1477 ·
I maintainer di solito rispondono entro 1 giorno
-
parity priority: low ui
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
storytold/pdfcraft#7483 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
IngvarConsulting/unica#3097 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement in-progress
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 64/100