Implement Spark-compatible `rlike` / `regexp` / `regexp_like`
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 33/100
Línea de trabajo
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.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Rust
- Estrellas
- 7
- Forks
- 15
- Merge medio
- 16 h 43 min
- PR fusionados (30 d)
- 26
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de apache/datafusion-spark
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
apache/datafusion-spark#287 ·
Los mantenedores suelen responder en 1 día
-
enhancement good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 80/100
apache/datafusion-spark#266 ·
Los mantenedores suelen responder en 1 día
-
[Bug] make_dt_interval returns NULL for more than about 1.49 million days, Spark returns the intervalPosiblemente ocupada @Subodh-17 la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
apache/datafusion-spark#109 ·
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 5/5 Más de una semana Aptitud para principiantes 18/100
apache/datafusion-spark#299 ·
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
apache/datafusion-spark#298 ·
Los mantenedores suelen responder en 1 día
Todos los issues de apache/datafusion-spark
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
storytold/photocraft#15232 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
suhina-daw/suhina-daw#1477 ·
Los mantenedores suelen responder en 1 día
-
parity priority: low ui
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
storytold/pdfcraft#7483 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
IngvarConsulting/unica#3097 ·
Los mantenedores suelen responder en 1 día
-
enhancement in-progress
Dificultad 1/5 Menos de una hora Aptitud para principiantes 64/100