pub trait ScalarFnVTable:
'static
+ Sized
+ Clone
+ Send
+ Sync {
type Options: 'static + Send + Sync + Clone + Debug + Display + PartialEq + Eq + Hash;
Show 14 methods
// Required methods
fn id(&self) -> ScalarFnId;
fn arity(&self, options: &Self::Options) -> Arity;
fn child_name(&self, options: &Self::Options, child_idx: usize) -> ChildName;
fn return_dtype(
&self,
options: &Self::Options,
args: &[DType],
) -> VortexResult<DType>;
fn execute(
&self,
options: &Self::Options,
args: &dyn ExecutionArgs,
ctx: &mut ExecutionCtx,
) -> VortexResult<ArrayRef>;
// Provided methods
fn serialize(
&self,
options: &Self::Options,
) -> VortexResult<Option<Vec<u8>>> { ... }
fn deserialize(
&self,
_metadata: &[u8],
_session: &VortexSession,
) -> VortexResult<Self::Options> { ... }
fn fmt_sql(
&self,
options: &Self::Options,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> Result { ... }
fn reduce<T: ReduceNode>(
&self,
options: &Self::Options,
node: &T,
) -> VortexResult<Option<T>> { ... }
fn simplify(
&self,
options: &Self::Options,
expr: &Expression,
ctx: &dyn SimplifyCtx,
) -> VortexResult<Option<Expression>> { ... }
fn simplify_untyped(
&self,
options: &Self::Options,
expr: &Expression,
) -> VortexResult<Option<Expression>> { ... }
fn validity(
&self,
options: &Self::Options,
expression: &Expression,
) -> VortexResult<Option<Expression>> { ... }
fn is_strict(&self, options: &Self::Options) -> bool { ... }
fn is_infallible(&self, options: &Self::Options) -> bool { ... }
}Expand description
This trait defines the interface for scalar function vtables, including methods for serialization, deserialization, validation, child naming, return type computation, and evaluation.
This trait is non-object safe and allows the implementer to make use of associated types for improved type safety, while allowing Vortex to enforce runtime checks on the inputs and outputs of each function.
The ScalarFnVTable trait should be implemented for a struct that holds global data across
all instances of the expression. In almost all cases, this struct will be an empty unit
struct, since most expressions do not require any global state.
Required Associated Types§
Required Methods§
Sourcefn id(&self) -> ScalarFnId
fn id(&self) -> ScalarFnId
Returns the ID of the scalar function vtable.
Sourcefn child_name(&self, options: &Self::Options, child_idx: usize) -> ChildName
fn child_name(&self, options: &Self::Options, child_idx: usize) -> ChildName
Returns the name of the nth child of the expr.
Sourcefn return_dtype(
&self,
options: &Self::Options,
args: &[DType],
) -> VortexResult<DType>
fn return_dtype( &self, options: &Self::Options, args: &[DType], ) -> VortexResult<DType>
Compute the return DType of the expression if evaluated over the given input types.
§Preconditions
The length of args must match the Arity of this function. Callers are responsible
for validating this (e.g., Expression::try_new checks arity at construction time).
Implementations may assume correct arity and will panic or return nonsensical results if
violated.
Sourcefn execute(
&self,
options: &Self::Options,
args: &dyn ExecutionArgs,
ctx: &mut ExecutionCtx,
) -> VortexResult<ArrayRef>
fn execute( &self, options: &Self::Options, args: &dyn ExecutionArgs, ctx: &mut ExecutionCtx, ) -> VortexResult<ArrayRef>
Execute the expression over the input arguments.
Implementations are encouraged to check their inputs for constant arrays to perform more optimized execution.
If the input arguments cannot be directly used for execution (for example, an expression
may require canonical input arrays), then the implementation should perform a single
child execution and return a new crate::arrays::ScalarFnArray wrapping up the new child.
This provides maximum opportunities for array-level optimizations using execute_parent kernels.
Provided Methods§
Sourcefn serialize(&self, options: &Self::Options) -> VortexResult<Option<Vec<u8>>>
fn serialize(&self, options: &Self::Options) -> VortexResult<Option<Vec<u8>>>
Serialize the options for this expression.
Should return Ok(None) if the expression is not serializable, and Ok(vec![]) if it is
serializable but has no metadata.
Sourcefn deserialize(
&self,
_metadata: &[u8],
_session: &VortexSession,
) -> VortexResult<Self::Options>
fn deserialize( &self, _metadata: &[u8], _session: &VortexSession, ) -> VortexResult<Self::Options>
Deserialize the options of this expression.
Sourcefn fmt_sql(
&self,
options: &Self::Options,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> Result
fn fmt_sql( &self, options: &Self::Options, expr: &dyn ExprDisplay, f: &mut Formatter<'_>, ) -> Result
Format an expression tree in a human-readable SQL-style format.
The expression may be either an Expression or a
bound expression.
Sourcefn reduce<T: ReduceNode>(
&self,
options: &Self::Options,
node: &T,
) -> VortexResult<Option<T>>
fn reduce<T: ReduceNode>( &self, options: &Self::Options, node: &T, ) -> VortexResult<Option<T>>
Implement an abstract reduction rule over a tree of scalar functions.
The ReduceNode can be used to traverse children, inspect their types, and
construct the result via ReduceNode::new_node. The rule is generic over the node
type and is instantiated once per reducible tree kind (expressions and arrays).
Return Ok(None) if no reduction is possible.
Sourcefn simplify(
&self,
options: &Self::Options,
expr: &Expression,
ctx: &dyn SimplifyCtx,
) -> VortexResult<Option<Expression>>
fn simplify( &self, options: &Self::Options, expr: &Expression, ctx: &dyn SimplifyCtx, ) -> VortexResult<Option<Expression>>
Simplify the expression if possible.
Sourcefn simplify_untyped(
&self,
options: &Self::Options,
expr: &Expression,
) -> VortexResult<Option<Expression>>
fn simplify_untyped( &self, options: &Self::Options, expr: &Expression, ) -> VortexResult<Option<Expression>>
Simplify the expression if possible, without type information.
Sourcefn validity(
&self,
options: &Self::Options,
expression: &Expression,
) -> VortexResult<Option<Expression>>
fn validity( &self, options: &Self::Options, expression: &Expression, ) -> VortexResult<Option<Expression>>
Returns an expression that evaluates to the validity of the result of this expression.
If a validity expression cannot be constructed, returns None and the expression will
be evaluated as normal before extracting the validity mask from the result.
This is essentially a specialized form of a reduce_parent
Sourcefn is_strict(&self, options: &Self::Options) -> bool
fn is_strict(&self, options: &Self::Options) -> bool
Returns whether this scalar function is strict.
A strict function returns null for a row when any argument is null for that row. This
matches PostgreSQL’s STRICT convention
for null propagation.
Return true only when this holds for every argument. add is strict, but Kleene AND
is not because false AND null returns false. is_null is also not strict.
Strictness does not require valid inputs to produce a valid output. For example,
crate::expr::list_sum returns null for a valid empty list. Implement
ScalarFnVTable::validity only when the output validity can be derived without
evaluation.
ScalarFnVTable::return_dtype must return a nullable output dtype when any input dtype is
nullable. A cast that forces a non-nullable output dtype is therefore not strict.
This property applies only to the scalar function, not its child expressions. Nullary
functions are vacuously strict. The default is conservatively false.
Sourcefn is_infallible(&self, options: &Self::Options) -> bool
fn is_infallible(&self, options: &Self::Options) -> bool
Returns whether this scalar function can never raise a semantic error.
Return true only when a well-typed call cannot error because of its values. checked_add
is fallible on integer overflow, and integer division is fallible when its divisor is zero.
A null result is not an error: crate::expr::list_sum is infallible for an empty list.
Ignore incidental execution errors, such as canonicalization failures, allocation errors, and encoding mismatches. They are not part of the function’s semantics.
Returning true permits optimizations that evaluate the function over values that no input
row references. Dictionary push-down, for example, evaluates every dictionary value, so a
fallible function could error on a value that row-wise evaluation would never reach.
This applies only to the scalar function, not its child expressions, and only to inputs
accepted by ScalarFnVTable::return_dtype. The default is conservatively false.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".