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

Function reduce_call_binary

src/expr/src/scalar/reduce/binary.rs:27–180  ·  view source on GitHub ↗
(
    e: &mut MirScalarExpr,
    column_types: &[ReprColumnType],
    temp_storage: &RowArena,
)

Source from the content-addressed store, hash-verified

25use crate::{Eval, EvalError, MirScalarExpr};
26
27pub(super) fn reduce_call_binary(
28 e: &mut MirScalarExpr,
29 column_types: &[ReprColumnType],
30 temp_storage: &RowArena,
31) {
32 let MirScalarExpr::CallBinary { func, expr1, expr2 } = e else {
33 unreachable!()
34 };
35
36 // Fold/propagate literal-shaped operands first; precompiles below assume
37 // these have already fired.
38 if expr1.is_literal() && expr2.is_literal() {
39 *e = MirScalarExpr::literal(e.eval(&[], temp_storage), e.typ(column_types).scalar_type);
40 return;
41 }
42 if (expr1.is_literal_null() || expr2.is_literal_null()) && func.propagates_nulls() {
43 *e = MirScalarExpr::literal_null(e.typ(column_types).scalar_type);
44 return;
45 }
46 if let Some(err) = expr1.as_literal_err() {
47 *e = MirScalarExpr::literal(Err(err.clone()), e.typ(column_types).scalar_type);
48 return;
49 }
50 if let Some(err) = expr2.as_literal_err() {
51 *e = MirScalarExpr::literal(Err(err.clone()), e.typ(column_types).scalar_type);
52 return;
53 }
54
55 // Calls where a literal operand makes the call the identity function on
56 // the other operand reduce to that operand.
57 if reduce_call_binary_identity(e) {
58 return;
59 }
60 let MirScalarExpr::CallBinary { func, expr1, expr2 } = e else {
61 unreachable!()
62 };
63
64 // Per-function dispatch. Each precompile fires only if its literal-shaped
65 // argument is present; otherwise the call falls through unchanged.
66 match func {
67 BinaryFunc::IsLikeMatchCaseInsensitive(_) if expr2.is_literal() => {
68 // We can at least precompile the regex.
69 precompile_is_like(e, column_types, true);
70 }
71 BinaryFunc::IsLikeMatchCaseSensitive(_) if expr2.is_literal() => {
72 // We can at least precompile the regex.
73 precompile_is_like(e, column_types, false);
74 }
75 BinaryFunc::IsRegexpMatchCaseSensitive(_) | BinaryFunc::IsRegexpMatchCaseInsensitive(_) => {
76 let case_insensitive = matches!(func, BinaryFunc::IsRegexpMatchCaseInsensitive(_));
77 if let MirScalarExpr::Literal(Ok(row), _) = &**expr2 {
78 *e = match Regex::new(row.unpack_first().unwrap_str(), case_insensitive) {
79 Ok(regex) => expr1
80 .take()
81 .call_unary(UnaryFunc::IsRegexpMatch(func::IsRegexpMatch(regex))),
82 Err(err) => {
83 MirScalarExpr::literal(Err(err.into()), e.typ(column_types).scalar_type)
84 }

Callers 1

reduce_postFunction · 0.85

Calls 15

precompile_is_likeFunction · 0.85
IsRegexpMatchClass · 0.85
precompile_date_unitsFunction · 0.85
ExtractIntervalClass · 0.85
ExtractTimeClass · 0.85
ExtractTimestampTzClass · 0.85
ExtractDateClass · 0.85
DatePartIntervalClass · 0.85
DatePartTimeClass · 0.85
DatePartTimestampClass · 0.85
DatePartTimestampTzClass · 0.85

Tested by

no test coverage detected