use vortex_error::VortexError;
use vortex_error::VortexResult;
use vortex_mask::Mask;
use vortex_mask::MaskValuesRef;
use super::super::RowFnExecutionArgs;
use super::super::args::BorrowedRowFnArgs;
use crate::ArrayRef;
use crate::ExecutionCtx;
use crate::builtins::ArrayBuiltins;
use crate::scalar_fn::unstable::row::execute::DenseAttempt;
use crate::validity::Validity;
impl RowFnExecutionArgs {
pub(super) fn execute_dense(
&self,
kernel: impl Fn(BorrowedRowFnArgs<'_>, &mut ExecutionCtx) -> VortexResult<ArrayRef>,
ctx: &mut ExecutionCtx,
) -> VortexResult<ArrayRef> {
let values = kernel(self.execution_args(&self.inputs, self.row_count), ctx)?;
self.finalize_dense_output(values, ctx)
}
pub(super) fn execute_dense_with_retry(
&self,
execute_dense_attempt: impl FnOnce(
BorrowedRowFnArgs<'_>,
&mut ExecutionCtx,
) -> VortexResult<DenseAttempt>,
try_valid_rows: impl FnOnce(
BorrowedRowFnArgs<'_>,
MaskValuesRef,
&mut ExecutionCtx,
) -> VortexResult<Option<ArrayRef>>,
execute_filtered_rows: impl FnOnce(
BorrowedRowFnArgs<'_>,
MaskValuesRef,
&mut ExecutionCtx,
) -> VortexResult<ArrayRef>,
ctx: &mut ExecutionCtx,
) -> VortexResult<ArrayRef> {
let attempt =
execute_dense_attempt(self.execution_args(&self.inputs, self.row_count), ctx)?;
match attempt {
DenseAttempt::Values(values) => self.finalize_dense_output(values, ctx),
DenseAttempt::DeferredError(error) => {
self.resolve_deferred_error(error, try_valid_rows, execute_filtered_rows, ctx)
}
}
}
fn resolve_deferred_error(
&self,
deferred_error: VortexError,
try_valid_rows: impl FnOnce(
BorrowedRowFnArgs<'_>,
MaskValuesRef,
&mut ExecutionCtx,
) -> VortexResult<Option<ArrayRef>>,
execute_filtered_rows: impl FnOnce(
BorrowedRowFnArgs<'_>,
MaskValuesRef,
&mut ExecutionCtx,
) -> VortexResult<ArrayRef>,
ctx: &mut ExecutionCtx,
) -> VortexResult<ArrayRef> {
let valid_rows = match self.validity.execute_mask(self.row_count, ctx)? {
Mask::AllTrue(_) | Mask::AllFalse(0) => return Err(deferred_error),
Mask::AllFalse(_) => return Ok(self.all_null()),
Mask::Values(valid_rows) => valid_rows,
};
drop(deferred_error);
if let Some(result) = self.try_execute_valid_rows(try_valid_rows, &valid_rows, ctx)? {
return Ok(result);
}
self.execute_filtered(execute_filtered_rows, &valid_rows, ctx)
}
fn finalize_dense_output(
&self,
values: ArrayRef,
ctx: &mut ExecutionCtx,
) -> VortexResult<ArrayRef> {
let values = self.validate_kernel_output(values, self.row_count, ctx)?;
match self.validity.clone() {
Validity::NonNullable | Validity::AllValid => {
self.finalize_output(values, self.row_count)
}
Validity::Array(valid) => self.finalize_output(values.mask(valid)?, self.row_count),
Validity::AllInvalid => {
unreachable!("all-invalid validity is handled before dense row execution")
}
}
}
}