Skip to content
Open
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
41 changes: 30 additions & 11 deletions datafusion/functions/src/regex/regexpinstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,17 +390,20 @@ fn get_index(
};
let search_slice = &value[byte_start_offset..];

// A subexpression, when requested, takes precedence over the N-th match.
// `n` is 1-based, `nth` is 0-based.
let nth = (n - 1) as usize;

// A subexpression, when requested, is located within the N-th match.
let match_start = if subexpr > 0 {
pattern
.captures(search_slice)
.captures_iter(search_slice)
.nth(nth)
.and_then(|captures| captures.get(subexpr as usize))
.map(|matched| matched.start())
} else {
// `n` is 1-based, `nth` is 0-based.
pattern
.find_iter(search_slice)
.nth((n - 1) as usize)
.nth(nth)
.map(|matched| matched.start())
};

Expand Down Expand Up @@ -685,13 +688,29 @@ mod tests {
}

fn test_case_sensitive_regexp_instr_scalar_subexp() {
let values = ["12 abc def ghi 34"];
let regex = ["(abc) (def) (ghi)"];
let start = [1];
let nth = [1];
let flags = ["i"];
let subexps = [2];
let expected: Vec<i64> = vec![8];
// The first row locates a subexpression in the only match. The rest
// locate one in the N-th match, including an N that has no match.
let values = [
"12 abc def ghi 34",
"12 abc def ghi 34 abc def ghi 56",
"12 abc def ghi 34 abc def ghi 56",
"12 abc def ghi 34 abc def ghi 56",
"12 abc def ghi 34 abc def ghi 56",
"12 abc def ghi 34 abc def ghi 56",
];
let regex = [
"(abc) (def) (ghi)",
"(abc) (def) (ghi)",
"(abc) (def) (ghi)",
"(abc) (def) (ghi)",
"(abc) (def) (ghi)",
"(abc) (def) (ghi)",
];
let start = [1, 1, 1, 1, 1, 18];
let nth = [1, 2, 2, 2, 3, 1];
let flags = ["i", "i", "i", "i", "i", "i"];
let subexps = [2, 1, 2, 3, 1, 2];
let expected: Vec<i64> = vec![8, 19, 23, 27, 0, 23];

izip!(
values.iter(),
Expand Down
12 changes: 12 additions & 0 deletions datafusion/sqllogictest/test_files/regexp/regexp_instr.slt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ SELECT
----
11

# The subexpression is located inside the N-th match, not inside the first one.
query I
SELECT regexp_instr('12 abc def ghi 34 abc def ghi 56', '(abc) (def) (ghi)', 1, 2, 'i', 2);
----
23

# There is no third match, so there is no position to report for any subexpression.
query I
SELECT regexp_instr('12 abc def ghi 34 abc def ghi 56', '(abc) (def) (ghi)', 1, 3, 'i', 1);
----
0

statement error DataFusion error: Arrow error: Compute error: regexp_instr\(\) requires start to be 1-based
SELECT regexp_instr('123123123123', '123', 0);

Expand Down