From 49004bb8f99c842fd54e05b880288a8653ac4fc8 Mon Sep 17 00:00:00 2001 From: Onur Satici Date: Thu, 4 Jun 2026 15:53:22 +0100 Subject: [PATCH] fix grouped sum index --- .../src/aggregate_fn/accumulator_grouped.rs | 5 +++-- vortex-array/src/aggregate_fn/fns/sum/mod.rs | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/vortex-array/src/aggregate_fn/accumulator_grouped.rs b/vortex-array/src/aggregate_fn/accumulator_grouped.rs index 3fae7a85bf3..ed651ba3d75 100644 --- a/vortex-array/src/aggregate_fn/accumulator_grouped.rs +++ b/vortex-array/src/aggregate_fn/accumulator_grouped.rs @@ -229,11 +229,12 @@ impl GroupedAccumulator { )?; let mut states = builder_with_capacity(&self.partial_dtype, offsets.len()); - for (offset, size) in offsets.iter().zip(sizes.iter()) { + for (i, (offset, size)) in offsets.iter().zip(sizes.iter()).enumerate() { let offset = offset.to_usize().vortex_expect("Offset value is not usize"); let size = size.to_usize().vortex_expect("Size value is not usize"); - if validity.value(offset) { + // validity is for the outer list view, so it must be indexed with `i` + if validity.value(i) { let group = elements.slice(offset..offset + size)?; accumulator.accumulate(&group, ctx)?; states.append_scalar(&accumulator.flush()?)?; diff --git a/vortex-array/src/aggregate_fn/fns/sum/mod.rs b/vortex-array/src/aggregate_fn/fns/sum/mod.rs index fb5f671e65d..24799570ff7 100644 --- a/vortex-array/src/aggregate_fn/fns/sum/mod.rs +++ b/vortex-array/src/aggregate_fn/fns/sum/mod.rs @@ -347,6 +347,7 @@ mod tests { use crate::arrays::ConstantArray; use crate::arrays::DecimalArray; use crate::arrays::FixedSizeListArray; + use crate::arrays::ListViewArray; use crate::arrays::PrimitiveArray; use crate::assert_arrays_eq; use crate::dtype::DType; @@ -616,6 +617,25 @@ mod tests { Ok(()) } + #[test] + fn grouped_sum_listview_out_of_order_offsets_with_null_group() -> VortexResult<()> { + let elements = + PrimitiveArray::new(buffer![100i32, 200, 300], Validity::NonNullable).into_array(); + let offsets = PrimitiveArray::new(buffer![2i32, 0, 1], Validity::NonNullable).into_array(); + let sizes = PrimitiveArray::new(buffer![1i32, 1, 1], Validity::NonNullable).into_array(); + let validity = Validity::from_iter([true, false, true]); + let groups = ListViewArray::try_new(elements, offsets, sizes, validity)?.into_array(); + + let elem_dtype = DType::Primitive(PType::I32, Nullability::NonNullable); + let result = run_grouped_sum(&groups, &elem_dtype)?; + + // group 0 -> elements[2..3] = 300; group 1 -> null; group 2 -> elements[1..2] = 200. + let expected = + PrimitiveArray::from_option_iter([Some(300i64), None, Some(200i64)]).into_array(); + assert_arrays_eq!(&result, &expected); + Ok(()) + } + // Chunked array tests #[test]