Expand description
Scalar expression evaluator — single owner of value-level
evaluation for SQL scalar Expr trees.
Today scalar expression evaluation is fragmented:
query::filter::Predicate::evaluateruns comparison predicates against a single column value.query::filter_compiled::CompiledFilter::evaluateruns the compiled filter opcode tape over a row slot, but still defers toPredicate::evaluateper opcode for the actual comparison logic.- Several inlined arms in
query::coreandquery::executorcompute projections, DEFAULT / CHECK expressions, RETURNING columns, COMPUTED columns, and ON CONFLICT updates by walking the AST and dispatching arithmetic / function calls inline. query::expr_typingknows how to type anExpragainst aScopebut never produces aValue— it stops atTypedExpr.
Operator / function / cast resolution is centralised in
schema::coercion_spine, but value-level dispatch is not — so
adding a new operator overload, a new implicit cast edge, or a
new built-in function requires synchronised edits across each of
the inline evaluators above.
This module is the first vertical slice of the deep evaluator
interface tracked by draft-53-scalar-expression-evaluator. It
exposes:
Row: pluggable column-binding lookup so callers can wire either a planner-resolved slot vector or a flat column-name map.evaluate: the single entry point. Walks anExpr, resolves operators / functions / casts throughcoercion_spine, applies the implicit casts the spine asks for, and produces aValue.EvalError: typed diagnostic surface — every failure mode the evaluator can encounter at runtime is enumerated here so callers don’t have to parse strings.
The slice is intentionally additive: callers in filter.rs,
filter_compiled.rs, and executor.rs still own their own
evaluation paths. Subsequent slices migrate those callers onto
evaluate once the dispatch surface has proven out under the
focused test set in this module.
§Semantics summary
- NULL propagation. Arithmetic, comparison, concat, and CAST
propagate
Value::Null— anyNulloperand short-circuits toNull.AND/ORfollow SQL three-valued logic. - Arithmetic overflow. Signed checked arithmetic; overflow
surfaces as
EvalError::ArithmeticOverflowrather than wrap or panic. - Division. Division by zero surfaces as
EvalError::DivisionByZero. Integer/always promotes toFloatper the operator catalog; integer%stays integer. - Implicit cast triggers. When the operator catalog has no
exact-type overload, the spine returns the per-operand
coercions; this evaluator applies them via
[
coerce::coerce_via_catalog] before dispatch. - Unknown function rejection. Calls that don’t resolve in the
built-in function catalog produce
EvalError::UnknownFunction. Variadic / catalog-resolved functions still return through the same dispatch.
Enums§
- Eval
Error - Errors surfaced by
evaluate. Every variant is a runtime failure shape — type-resolution failures live inexpr_typing::TypeError, not here.
Traits§
- Row
- Pluggable row-binding lookup. The evaluator stays agnostic of
whether the caller has a slot vector indexed by planner-assigned
position, a flat
HashMap<String, Value>, or a graph binding — every consumer just provides aRowimpl that resolves aFieldRefto aValue.
Functions§
- evaluate
- Evaluate a scalar
Expragainst a row binding. Single entry point for the deep evaluator interface — every recursive call folds back through this function so the resolution surface stays uniform.