in arrow-string/src/like.rs [278:323]
fn like_scalar_op<'a, F: Fn(bool) -> bool, L: ArrayAccessor<Item = &'a str>>(
left: L,
right: &str,
op: F,
) -> Result<BooleanArray, ArrowError> {
if !right.contains(is_like_pattern) {
// fast path, can use equals
Ok(BooleanArray::from_unary(left, |item| op(item == right)))
} else if right.ends_with('%')
&& !right.ends_with("\\%")
&& !right[..right.len() - 1].contains(is_like_pattern)
{
// fast path, can use starts_with
let starts_with = &right[..right.len() - 1];
Ok(BooleanArray::from_unary(left, |item| {
op(item.starts_with(starts_with))
}))
} else if right.starts_with('%') && !right[1..].contains(is_like_pattern) {
// fast path, can use ends_with
let ends_with = &right[1..];
Ok(BooleanArray::from_unary(left, |item| {
op(item.ends_with(ends_with))
}))
} else if right.starts_with('%')
&& right.ends_with('%')
&& !right.ends_with("\\%")
&& !right[1..right.len() - 1].contains(is_like_pattern)
{
let contains = &right[1..right.len() - 1];
Ok(BooleanArray::from_unary(left, |item| {
op(item.contains(contains))
}))
} else {
let re_pattern = replace_like_wildcards(right)?;
let re = Regex::new(&format!("(?s)^{re_pattern}$")).map_err(|e| {
ArrowError::ComputeError(format!(
"Unable to build regex from LIKE pattern: {e}"
))
})?;
Ok(BooleanArray::from_unary(left, |item| op(re.is_match(item))))
}
}