From 67efcce553ad76a64660138fe2b495aa1ab45a93 Mon Sep 17 00:00:00 2001 From: Matt Katz Date: Tue, 21 Jul 2026 13:17:06 -0700 Subject: [PATCH] mask listview preserves zctl Signed-off-by: Matt Katz --- vortex-array/src/arrays/masked/execute.rs | 2 ++ vortex-array/src/arrays/masked/tests.rs | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/vortex-array/src/arrays/masked/execute.rs b/vortex-array/src/arrays/masked/execute.rs index c4173dd0cf6..0de8be7321e 100644 --- a/vortex-array/src/arrays/masked/execute.rs +++ b/vortex-array/src/arrays/masked/execute.rs @@ -110,6 +110,7 @@ fn mask_validity_varbinview( fn mask_validity_listview(array: ListViewArray, validity: Validity) -> VortexResult { let new_validity = Validity::and(array.validity()?, validity)?; // SAFETY: We're only changing validity, not the data structure + let is_zctl = array.is_zero_copy_to_list(); Ok(unsafe { ListViewArray::new_unchecked( array.elements().clone(), @@ -117,6 +118,7 @@ fn mask_validity_listview(array: ListViewArray, validity: Validity) -> VortexRes array.sizes().clone(), new_validity, ) + .with_zero_copy_to_list(is_zctl) }) } diff --git a/vortex-array/src/arrays/masked/tests.rs b/vortex-array/src/arrays/masked/tests.rs index 842599bfa52..92ec4eb474f 100644 --- a/vortex-array/src/arrays/masked/tests.rs +++ b/vortex-array/src/arrays/masked/tests.rs @@ -10,6 +10,7 @@ use crate::Canonical; use crate::IntoArray; use crate::VortexSessionExecute; use crate::array_session; +use crate::arrays::ListViewArray; use crate::arrays::PrimitiveArray; use crate::assert_arrays_eq; use crate::dtype::DType; @@ -140,3 +141,23 @@ fn test_masked_child_preserves_length(#[case] validity: Validity) { .unwrap(), ); } + +#[test] +fn masked_listview_execute_preserves_zctl_true() -> VortexResult<()> { + // Masking only intersects validity, so the zero-copy-to-list survives + // execution. + let elements = PrimitiveArray::from_iter([1i32, 2, 3]).into_array(); + let offsets = PrimitiveArray::from_iter([0i32, 2]).into_array(); + let sizes = PrimitiveArray::from_iter([2i32, 1]).into_array(); + let list_view = unsafe { + ListViewArray::new_unchecked(elements, offsets, sizes, Validity::NonNullable) + .with_zero_copy_to_list(true) + }; + + let masked = MaskedArray::try_new(list_view.into_array(), Validity::from_iter([true, false]))?; + let canonical = masked + .into_array() + .execute::(&mut array_session().create_execution_ctx())?; + assert!(canonical.into_listview().is_zero_copy_to_list()); + Ok(()) +}