/// Given a column containing string values and a single regex pattern,
/// `regex_match_expr` determines which values satisfy the pattern and which do
/// not.
///
/// If `matches` is true then this expression will filter values that do not
/// satisfy the regex (equivalent to `col ~= /pattern/`). If `matches` is `false`
/// then the expression will filter values that *do* match the regex, which is
/// equivalent to `col !~ /pattern/`.
///
/// This UDF is designed to support the regex operator that can be pushed down
/// via the InfluxRPC API.
///
Given a column containing string values and a single regex pattern,
`regex_match_expr` determines which values satisfy the pattern and which do
not.

If `matches` is true then this expression will filter values that do not
satisfy the regex (equivalent to `col ~= /pattern/`).

This UDF is designed to support the regex operator that can be pushed down
via the InfluxRPC API.
Given a column containing string values and a single regex pattern ` regex_match_expr ` determines which values satisfy the pattern and which do not . If ` matches ` is true then this expression will filter values that do not satisfy the regex ( equivalent to ` col ~ = / pattern / ` ) . This UDF is designed to support the regex operator that can be pushed down via the InfluxRPC API .
fn regex_match_expr_impl(matches: bool) -> ScalarFunctionImplementation {
    // N.B., this function does not utilise the Arrow regexp compute
    // kernel because in order to act as a filter it needs to return a
    // boolean array of comparison results, not an array of strings as
    // the regex compute kernel does and it needs to implement the
    // regexp syntax for influxrpc.
    let func = move |args: &[ColumnarValue]| {
        assert_eq!(args.len(), 2); // only works over a single column and pattern at a time.
        let pattern = match &args[1] {
            // second arg was array (not constant)
            ColumnarValue::Array(_) => {
                return Err(DataFusionError::NotImplemented(format!(
                    "regex_match({}) with non scalar patterns not yet implemented",
                    matches
                )))
            }
            ColumnarValue::Scalar(ScalarValue::Utf8(pattern)) => pattern,
            ColumnarValue::Scalar(arg) => {
                return Err(DataFusionError::Internal(format!(
                    "Expected string pattern to regex match({}), got: {:?}",
                    matches, arg
                )))
            }
        };
        let pattern = pattern.as_ref().ok_or_else(|| {
            DataFusionError::NotImplemented(
                "NULL patterns not supported in regex match".to_string(),
            )
        })?;
        // Attempt to make the pattern compatible with what is accepted by
        // the golang regexp library which is different than Rust's regexp
        let pattern = clean_non_meta_escapes(pattern);
        let pattern = regex::Regex::new(&pattern).map_err(|e| {
            DataFusionError::Internal(format!("error compiling regex pattern: {}", e))
        })?;
        match &args[0] {
            ColumnarValue::Array(arr) => {
                let results = as_string_array(arr)
                    .iter()
                    .map(|row| {
                        // in arrow, any value can be null.
                        // Here we decide to make our UDF to return null when either base or exponent is null.
                        row.map(|v| pattern.is_match(v) == matches)
                    })
                    .collect::<BooleanArray>();
                Ok(ColumnarValue::Array(Arc::new(results) as ArrayRef))
            }
            ColumnarValue::Scalar(ScalarValue::Utf8(row)) => {
                let res = row.as_ref().map(|v| pattern.is_match(v) == matches);
                Ok(ColumnarValue::Scalar(ScalarValue::Boolean(res)))
            }
            ColumnarValue::Scalar(v) => {
                return Err(DataFusionError::Internal(format!(
                    "regex_match({}) expected first argument to be utf8, got ('{}')",
                    matches, v
                )))
            }
        }
    };
    Arc::new(func)
}
fn regex_match_expr_impl ( matches : bool ) -> ScalarFunctionImplementation { // N.B., this function does not utilise the Arrow regexp compute // kernel because in order to act as a filter it needs to return a // boolean array of comparison results, not an array of strings as // the regex compute kernel does and it needs to implement the // regexp syntax for influxrpc. let func = move | args : & [ ColumnarValue ] | { assert_eq ! ( args len ( ) 2 ) ; // only works over a single column and pattern at a time. let pattern = match & args [ 1 ] { // second arg was array (not constant) ColumnarValue :: Array ( _ ) => { return Err ( DataFusionError :: NotImplemented ( format ! ( " " matches ) ) ) } ColumnarValue :: Scalar ( ScalarValue :: Utf8 ( pattern ) ) => pattern , ColumnarValue :: Scalar ( arg ) => { return Err ( DataFusionError :: Internal ( format ! ( " " matches arg ) ) ) } } ; let pattern = pattern . as_ref ( ) . ok_or_else ( | | { DataFusionError :: NotImplemented ( " " . to_string ( ) , ) } ) ? ; // Attempt to make the pattern compatible with what is accepted by // the golang regexp library which is different than Rust's regexp let pattern = clean_non_meta_escapes ( pattern ) ; let pattern = regex :: Regex :: new ( & pattern ) . map_err ( | e | { DataFusionError :: Internal ( format ! ( " " e ) ) } ) ? ; match & args [ 0 ] { ColumnarValue :: Array ( arr ) => { let results = as_string_array ( arr ) . iter ( ) . map ( | row | { // in arrow, any value can be null. // Here we decide to make our UDF to return null when either base or exponent is null. row . map ( | v | pattern . is_match ( v ) == matches ) } ) . collect :: < BooleanArray > ( ) ; Ok ( ColumnarValue :: Array ( Arc :: new ( results ) as ArrayRef ) ) } ColumnarValue :: Scalar ( ScalarValue :: Utf8 ( row ) ) => { let res = row . as_ref ( ) . map ( | v | pattern . is_match ( v ) == matches ) ; Ok ( ColumnarValue :: Scalar ( ScalarValue :: Boolean ( res ) ) ) } ColumnarValue :: Scalar ( v ) => { return Err ( DataFusionError :: Internal ( format ! ( " " matches v ) ) ) } } } ; Arc :: new ( func ) }
Given a column containing string values and a single regex pattern,
`regex_match_expr` determines which values satisfy the pattern and which do
not.
Given a column containing string values and a single regex pattern ` regex_match_expr ` determines which values satisfy the pattern and which do not .
matches
bool