use vortex_error::VortexResult;
use vortex_error::vortex_bail;
use crate::ArrayRef;
use crate::ExecutionCtx;
use crate::IntoArray;
use crate::VortexSessionExecute;
use crate::array::ArrayView;
use crate::array::ValidityVTable;
use crate::arrays::ConstantArray;
use crate::arrays::scalar_fn::ScalarFnArrayExt;
use crate::arrays::scalar_fn::vtable::ArrayExpr;
use crate::arrays::scalar_fn::vtable::FakeEq;
use crate::arrays::scalar_fn::vtable::ScalarFn;
use crate::expr::Expression;
use crate::expr::lit;
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;
fn execute_expr(
expr: &Expression,
row_count: usize,
ctx: &mut ExecutionCtx,
) -> VortexResult<ArrayRef> {
if expr.is::<Root>() {
vortex_bail!("Root expression cannot be executed in validity context");
}
if expr.is::<Literal>() {
let scalar = expr.as_::<Literal>();
return Ok(ConstantArray::new(scalar.clone(), row_count).into_array());
}
let inputs: Vec<ArrayRef> = expr
.children()
.iter()
.map(|child| execute_expr(child, row_count, ctx))
.collect::<VortexResult<_>>()?;
let args = VecExecutionArgs::new(inputs, row_count);
Ok(expr.scalar_fn().execute(&args, ctx)?.into_array())
}
impl ValidityVTable<ScalarFn> for ScalarFn {
fn validity(array: ArrayView<'_, ScalarFn>) -> VortexResult<Validity> {
let inputs: Vec<_> = array
.iter_children()
.map(|child| {
if let Some(scalar) = child.as_constant() {
return Ok(lit(scalar));
}
Expression::try_new(
TypedScalarFnInstance::new(ArrayExpr, FakeEq(child.clone())).erased(),
[],
)
})
.collect::<VortexResult<_>>()?;
let expr = Expression::try_new(array.scalar_fn().clone(), inputs)?;
let validity_expr = array.scalar_fn().validity(&expr)?;
#[allow(clippy::disallowed_methods)]
let ctx = &mut legacy_session().create_execution_ctx();
Ok(Validity::Array(execute_expr(
&validity_expr,
array.len(),
ctx,
)?))
}
}