Trait mz_expr::scalar::func::LazyUnaryFunc
source · trait LazyUnaryFunc {
// Required methods
fn eval<'a>(
&'a self,
datums: &[Datum<'a>],
temp_storage: &'a RowArena,
a: &'a MirScalarExpr,
) -> Result<Datum<'a>, EvalError>;
fn output_type(&self, input_type: ColumnType) -> ColumnType;
fn propagates_nulls(&self) -> bool;
fn introduces_nulls(&self) -> bool;
fn preserves_uniqueness(&self) -> bool;
fn inverse(&self) -> Option<UnaryFunc>;
fn is_monotone(&self) -> bool;
// Provided method
fn could_error(&self) -> bool { ... }
}
Expand description
A description of an SQL unary function that has the ability to lazy evaluate its arguments
Required Methods§
fn eval<'a>( &'a self, datums: &[Datum<'a>], temp_storage: &'a RowArena, a: &'a MirScalarExpr, ) -> Result<Datum<'a>, EvalError>
sourcefn output_type(&self, input_type: ColumnType) -> ColumnType
fn output_type(&self, input_type: ColumnType) -> ColumnType
The output ColumnType of this function.
sourcefn propagates_nulls(&self) -> bool
fn propagates_nulls(&self) -> bool
Whether this function will produce NULL on NULL input.
sourcefn introduces_nulls(&self) -> bool
fn introduces_nulls(&self) -> bool
Whether this function will produce NULL on non-NULL input.
sourcefn preserves_uniqueness(&self) -> bool
fn preserves_uniqueness(&self) -> bool
Whether this function preserves uniqueness.
Uniqueness is preserved when if f(x) = f(y) then x = y
is true. This
is used by the optimizer when a guarantee can be made that a collection
with unique items will stay unique when mapped by this function.
Note that error results are not covered: Even with preserves_uniqueness = true
, it can
happen that two different inputs produce the same error result. (e.g., in case of a
narrowing cast)
Functions should conservatively return false
unless they are certain
the above property is true.
sourcefn inverse(&self) -> Option<UnaryFunc>
fn inverse(&self) -> Option<UnaryFunc>
The inverse of this function, if it has one and we have determined it.
The optimizer can use this information when selecting indexes, e.g. an indexed column has a cast applied to it, by moving the right inverse of the cast to another value, we can select the indexed column.
Note that a value of None
does not imply that the inverse does not
exist; it could also mean we have not yet invested the energy in
representing it. For example, in the case of complex casts, such as
between two list types, we could determine the right inverse, but doing
so is not immediately necessary as this information is only used by the
optimizer.
§Right vs. left vs. inverses
- Right inverses are when the inverse function preserves uniqueness. These are the functions that the optimizer uses to move casts between expressions.
- Left inverses are when the function itself preserves uniqueness.
- Inverses are when a function is both a right and a left inverse (e.g., bit_not_int64 is both a right and left inverse of itself).
We call this function inverse
for simplicity’s sake; it doesn’t always
correspond to the mathematical notion of “inverse.” However, in
conjunction with checks to preserves_uniqueness
you can determine
which type of inverse we return.
sourcefn is_monotone(&self) -> bool
fn is_monotone(&self) -> bool
Returns true if the function is monotone. (Non-strict; either increasing or decreasing.) Monotone functions map ranges to ranges: ie. given a range of possible inputs, we can determine the range of possible outputs just by mapping the endpoints.
This property describes the behaviour of the function over ranges where the function is defined: ie. the argument and the result are non-error datums.
Provided Methods§
sourcefn could_error(&self) -> bool
fn could_error(&self) -> bool
Whether this function might error on non-error input.