diff --git a/vortex-array/src/arrays/shared/vtable.rs b/vortex-array/src/arrays/shared/vtable.rs index 3c3a09216d2..fc03255d785 100644 --- a/vortex-array/src/arrays/shared/vtable.rs +++ b/vortex-array/src/arrays/shared/vtable.rs @@ -113,6 +113,14 @@ impl VTable for Shared { .get_or_compute(|source| source.clone().execute::(ctx)) .map(ExecutionResult::done) } + + fn reduce_parent( + array: ArrayView<'_, Self>, + parent: &ArrayRef, + child_idx: usize, + ) -> VortexResult> { + array.current_array_ref().reduce_parent(parent, child_idx) + } } impl OperationsVTable for Shared { fn scalar_at( diff --git a/vortex-array/src/executor.rs b/vortex-array/src/executor.rs index 0c083f18ee5..b09c2d048b9 100644 --- a/vortex-array/src/executor.rs +++ b/vortex-array/src/executor.rs @@ -34,6 +34,8 @@ use crate::ArrayRef; use crate::Canonical; use crate::IntoArray; use crate::array::ArrayId; +use crate::arrays::Shared; +use crate::arrays::shared::SharedArrayExt; use crate::builders::ArrayBuilder; use crate::builders::builder_with_capacity_in; use crate::dtype::DType; @@ -568,6 +570,35 @@ fn execute_parent_for_child( slot_idx: usize, kernels: &ParentExecutionKernels, ctx: &mut ExecutionCtx, +) -> VortexResult> { + if let Some(result) = execute_parent_for_exact_child(parent, child, slot_idx, kernels, ctx)? { + return Ok(Some(result)); + } + + // Shared is a transparent cache wrapper. Try kernels against the wrapped source/current array + // before forcing Shared to canonicalize and populate its cache. + let mut current = child.clone(); + while let Some(source) = current + .as_opt::() + .map(|shared| shared.current_array_ref().clone()) + { + if let Some(result) = + execute_parent_for_exact_child(parent, &source, slot_idx, kernels, ctx)? + { + return Ok(Some(result)); + } + current = source; + } + + Ok(None) +} + +fn execute_parent_for_exact_child( + parent: &ArrayRef, + child: &ArrayRef, + slot_idx: usize, + kernels: &ParentExecutionKernels, + ctx: &mut ExecutionCtx, ) -> VortexResult> { let key = execute_parent_key(parent.encoding_id(), child.encoding_id()); if let Some(plugins) = kernels.get(&key) {