From 208af9b8e1447316c957f4593f754374e6253755 Mon Sep 17 00:00:00 2001 From: Matt Katz Date: Thu, 6 Aug 2026 11:10:28 -0700 Subject: [PATCH 1/4] root as expression variant Signed-off-by: Matt Katz --- .../src/arrays/scalar_fn/vtable/validity.rs | 9 +- vortex-array/src/expr/analysis/fallible.rs | 6 +- .../src/expr/analysis/immediate_access.rs | 7 +- vortex-array/src/expr/analysis/strict.rs | 7 +- vortex-array/src/expr/bound_expression.rs | 8 +- vortex-array/src/expr/display.rs | 21 +- vortex-array/src/expr/expression.rs | 181 +++++++++++++----- vortex-array/src/expr/exprs.rs | 13 +- vortex-array/src/expr/mod.rs | 29 ++- vortex-array/src/expr/optimize.rs | 61 ++++-- vortex-array/src/expr/proto.rs | 38 +++- vortex-array/src/expr/transform/coerce.rs | 8 +- vortex-array/src/expr/traversal/mod.rs | 10 +- vortex-array/src/expression.rs | 10 +- vortex-array/src/scalar_fn/fns/between/mod.rs | 2 +- vortex-array/src/scalar_fn/fns/dynamic.rs | 2 +- vortex-array/src/scalar_fn/fns/get_item.rs | 2 +- vortex-array/src/scalar_fn/fns/is_not_null.rs | 6 +- vortex-array/src/scalar_fn/fns/is_null.rs | 6 +- vortex-array/src/scalar_fn/fns/like/mod.rs | 4 +- vortex-array/src/scalar_fn/fns/mod.rs | 1 - vortex-array/src/scalar_fn/fns/not/mod.rs | 2 +- vortex-array/src/scalar_fn/fns/root.rs | 87 --------- vortex-array/src/scalar_fn/session.rs | 2 - vortex-array/src/stats/rewrite.rs | 9 +- 25 files changed, 309 insertions(+), 222 deletions(-) delete mode 100644 vortex-array/src/scalar_fn/fns/root.rs diff --git a/vortex-array/src/arrays/scalar_fn/vtable/validity.rs b/vortex-array/src/arrays/scalar_fn/vtable/validity.rs index 39ab8c2c466..86997a96cfe 100644 --- a/vortex-array/src/arrays/scalar_fn/vtable/validity.rs +++ b/vortex-array/src/arrays/scalar_fn/vtable/validity.rs @@ -21,7 +21,6 @@ use crate::legacy_session; use crate::scalar_fn::TypedScalarFnInstance; use crate::scalar_fn::VecExecutionArgs; use crate::scalar_fn::fns::literal::Literal; -use crate::scalar_fn::fns::root::Root; use crate::validity::Validity; /// Execute an expression tree recursively. @@ -32,10 +31,10 @@ fn execute_expr( row_count: usize, ctx: &mut ExecutionCtx, ) -> VortexResult { - // Handle Root expression - this should not happen in validity expressions - if expr.is::() { + // Root is not executable; a validity expression should never contain one. + let Some(scalar_fn) = expr.as_scalar() else { vortex_bail!("Root expression cannot be executed in validity context"); - } + }; // Handle Literal expression - create a constant array if expr.is::() { @@ -52,7 +51,7 @@ fn execute_expr( let args = VecExecutionArgs::new(inputs, row_count); - Ok(expr.scalar_fn().execute(&args, ctx)?.into_array()) + Ok(scalar_fn.execute(&args, ctx)?.into_array()) } impl ValidityVTable for ScalarFn { diff --git a/vortex-array/src/expr/analysis/fallible.rs b/vortex-array/src/expr/analysis/fallible.rs index b6d45bd5483..ff43d51603b 100644 --- a/vortex-array/src/expr/analysis/fallible.rs +++ b/vortex-array/src/expr/analysis/fallible.rs @@ -8,7 +8,11 @@ use crate::expr::label_tree; pub fn label_is_fallible(expr: &Expression) -> BooleanLabels<'_> { label_tree( expr, - |expr| expr.signature().is_fallible(), + |expr| match expr { + Expression::Scalar { scalar_fn, .. } => scalar_fn.signature().is_fallible(), + // The scope itself cannot fail. + Expression::Root => false, + }, |acc, &child| acc | child, ) } diff --git a/vortex-array/src/expr/analysis/immediate_access.rs b/vortex-array/src/expr/analysis/immediate_access.rs index fd720607284..612552ce4e5 100644 --- a/vortex-array/src/expr/analysis/immediate_access.rs +++ b/vortex-array/src/expr/analysis/immediate_access.rs @@ -9,7 +9,6 @@ use crate::expr::BoundExpression; use crate::expr::Expression; use crate::expr::analysis::AnnotationFn; use crate::scalar_fn::fns::get_item::GetItem; -use crate::scalar_fn::fns::root::Root; use crate::scalar_fn::fns::select::Select; /// Returns the "free fields" for this expression node. @@ -42,7 +41,7 @@ pub fn make_free_field_annotator( ) -> impl AnnotationFn { move |expr: &Expression| { if let Some(selection) = expr.as_opt::