MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / regexp_matches

Function regexp_matches

src/expr/src/relation/func.rs:2971–3025  ·  view source on GitHub ↗
(
    exprs: &[Datum<'a>],
)

Source from the content-addressed store, hash-verified

2969}
2970
2971fn regexp_matches<'a>(
2972 exprs: &[Datum<'a>],
2973) -> Result<impl Iterator<Item = (Row, Diff)> + 'a, EvalError> {
2974 // There are only two acceptable ways to call this function:
2975 // 1. regexp_matches(string, regex)
2976 // 2. regexp_matches(string, regex, flag)
2977 assert!(exprs.len() == 2 || exprs.len() == 3);
2978 let a = exprs[0].unwrap_str();
2979 let r = exprs[1].unwrap_str();
2980
2981 let (regex, opts) = if exprs.len() == 3 {
2982 let flag = exprs[2].unwrap_str();
2983 let opts = AnalyzedRegexOpts::from_str(flag)?;
2984 (AnalyzedRegex::new(r, opts)?, opts)
2985 } else {
2986 let opts = AnalyzedRegexOpts::default();
2987 (AnalyzedRegex::new(r, opts)?, opts)
2988 };
2989
2990 let regex = regex.inner().clone();
2991
2992 let iter = regex.captures_iter(a).map(move |captures| {
2993 let matches = captures
2994 .iter()
2995 // The first match is the *entire* match, we want the capture groups by themselves.
2996 .skip(1)
2997 .map(|m| Datum::from(m.map(|m| m.as_str())))
2998 .collect::<Vec<_>>();
2999
3000 let mut binding = SharedRow::get();
3001 let mut packer = binding.packer();
3002
3003 let dimension = ArrayDimension {
3004 lower_bound: 1,
3005 length: matches.len(),
3006 };
3007 packer
3008 .try_push_array(&[dimension], matches)
3009 .expect("generated dimensions above");
3010
3011 (binding.clone(), Diff::ONE)
3012 });
3013
3014 // This is slightly unfortunate, but we need to collect the captures into a
3015 // Vec before we can yield them, because we can't return a iter with a
3016 // reference to the local `regex` variable.
3017 // We attempt to minimize the cost of this by using a SmallVec.
3018 let out = iter.collect::<SmallVec<[_; 3]>>();
3019
3020 if opts.global {
3021 Ok(Either::Left(out.into_iter()))
3022 } else {
3023 Ok(Either::Right(out.into_iter().take(1)))
3024 }
3025}
3026
3027fn generate_series<N>(
3028 start: N,

Callers 1

evalMethod · 0.85

Calls 14

unwrap_strMethod · 0.80
packerMethod · 0.80
expectMethod · 0.80
try_push_arrayMethod · 0.80
getFunction · 0.50
lenMethod · 0.45
cloneMethod · 0.45
innerMethod · 0.45
mapMethod · 0.45
skipMethod · 0.45
iterMethod · 0.45
as_strMethod · 0.45

Tested by

no test coverage detected