# 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>

source#### fn output_type(&self, input_type: ColumnType) -> ColumnType

#### fn output_type(&self, input_type: ColumnType) -> ColumnType

The output ColumnType of this function.

source#### fn propagates_nulls(&self) -> bool

#### fn propagates_nulls(&self) -> bool

Whether this function will produce NULL on NULL input.

source#### fn introduces_nulls(&self) -> bool

#### fn introduces_nulls(&self) -> bool

Whether this function will produce NULL on non-NULL input.

source#### fn 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.

source#### fn 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.

source#### fn 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§

source#### fn could_error(&self) -> bool

#### fn could_error(&self) -> bool

Whether this function might error on non-error input.