Skip to content

Commit 8e8fdc6

Browse files
committed
Adapt list_sum to ctx-threaded finish; drop redundant mask_empty_lists and dead code
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
1 parent 9abea9c commit 8e8fdc6

3 files changed

Lines changed: 3 additions & 67 deletions

File tree

vortex-array/src/aggregate_fn/fns/sum/mod.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -502,16 +502,6 @@ fn sum_value_scalar(partial: &SumPartial) -> Scalar {
502502
}
503503
}
504504

505-
/// Whether the array contains at least one valid element. NaNs are valid values: with
506-
/// `skip_nans` they contribute nothing to the sum, but a sum over only NaNs is `0`, not null.
507-
fn has_valid_values(array: &ArrayRef, ctx: &mut ExecutionCtx) -> VortexResult<bool> {
508-
Ok(array
509-
.validity()?
510-
.execute_mask(array.len(), ctx)?
511-
.true_count()
512-
> 0)
513-
}
514-
515505
/// The accumulated sum value.
516506
// TODO(ngates): instead of an enum, we should use a Box<dyn State> to avoid dispatcher over the
517507
// input type every time? Perhaps?

vortex-array/src/scalar_fn/fns/list_sum.rs

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
33

4-
use vortex_buffer::BitBuffer;
54
use vortex_error::VortexResult;
65
use vortex_error::vortex_bail;
76
use vortex_error::vortex_err;
8-
use vortex_mask::AllOr;
97
use vortex_session::VortexSession;
108
use vortex_session::registry::CachedId;
119

@@ -16,23 +14,16 @@ use crate::ExecutionCtx;
1614
use crate::IntoArray;
1715
use crate::aggregate_fn::AggregateFnVTable;
1816
use crate::aggregate_fn::DynGroupedAccumulator;
19-
use crate::aggregate_fn::GroupRanges;
2017
use crate::aggregate_fn::GroupedAccumulator;
21-
use crate::aggregate_fn::GroupedArray;
2218
use crate::aggregate_fn::NumericalAggregateOpts;
2319
use crate::aggregate_fn::fns::sum::Sum;
24-
use crate::arrays::BoolArray;
2520
use crate::arrays::ConstantArray;
26-
use crate::arrays::FixedSizeList;
27-
use crate::arrays::ListView;
28-
use crate::builtins::ArrayBuiltins;
2921
use crate::dtype::DType;
3022
use crate::scalar_fn::Arity;
3123
use crate::scalar_fn::ChildName;
3224
use crate::scalar_fn::ExecutionArgs;
3325
use crate::scalar_fn::ScalarFnId;
3426
use crate::scalar_fn::ScalarFnVTable;
35-
use crate::validity::Validity;
3627

3728
/// Sum of the elements in each list of a `List` or `FixedSizeList` typed array.
3829
///
@@ -100,7 +91,6 @@ impl ScalarFnVTable for ListSum {
10091
other => vortex_bail!("list_sum() requires List or FixedSizeList, got {other}"),
10192
};
10293

103-
// `mask_empty_lists` needs access to list elements validity and sizes
10494
let columnar = input.execute::<Columnar>(ctx)?;
10595

10696
match columnar {
@@ -131,8 +121,8 @@ impl ScalarFnVTable for ListSum {
131121

132122
/// Sum each list of a canonical `array` into one value per list.
133123
///
134-
/// Note that we need to nullify sums produced by empty or all-null lists,
135-
/// since grouped sum kernels default to 0 for these.
124+
/// The grouped [`Sum`] finalize already yields null for null, empty, and all-null lists
125+
/// (SQL `SUM` semantics), so no post-processing is needed.
136126
fn list_sum_impl(
137127
canonical: ArrayRef,
138128
elem_dtype: DType,
@@ -141,50 +131,7 @@ fn list_sum_impl(
141131
) -> VortexResult<ArrayRef> {
142132
let mut acc = GroupedAccumulator::try_new(Sum, *options, elem_dtype)?;
143133
acc.accumulate_list(&canonical, ctx)?;
144-
let sums = acc.finish()?;
145-
146-
let grouped: GroupedArray = if let Some(fsl) = canonical.as_opt::<FixedSizeList>() {
147-
fsl.into_owned().into()
148-
} else if let Some(lv) = canonical.as_opt::<ListView>() {
149-
lv.into_owned().into()
150-
} else {
151-
let dtype = canonical.dtype();
152-
vortex_bail!("list_sum() requires List or FixedSizeList but got {dtype}")
153-
};
154-
155-
mask_empty_lists(grouped, sums, ctx)
156-
}
157-
158-
/// Applies a mask to `sums` that nullifies entries produced by lists without at least
159-
/// one valid element. This is necessary because the grouped `Sum` aggregate only produces
160-
/// nulls for null lists and sums that overflow.
161-
fn mask_empty_lists(
162-
grouped: GroupedArray,
163-
sums: ArrayRef,
164-
ctx: &mut ExecutionCtx,
165-
) -> VortexResult<ArrayRef> {
166-
let elements = grouped.elements();
167-
let elem_mask = elements.validity()?.execute_mask(elements.len(), ctx)?;
168-
let ranges = grouped.group_ranges(ctx)?;
169-
170-
let has_valid_element: BitBuffer = match elem_mask.bit_buffer() {
171-
AllOr::All => match &ranges {
172-
// fixed-size lists of non-zero width cannot have empty lists.
173-
GroupRanges::FixedSizeList { size, .. } if *size > 0 => return Ok(sums),
174-
GroupRanges::FixedSizeList { len, .. } => BitBuffer::full(false, *len),
175-
GroupRanges::ListView { ranges } => ranges.iter().map(|&(_, size)| size > 0).collect(),
176-
},
177-
AllOr::None => BitBuffer::full(false, ranges.len()),
178-
AllOr::Some(bits) => ranges
179-
.iter()
180-
.map(|(offset, size)| size > 0 && bits.count_range(offset, offset + size) > 0)
181-
.collect(),
182-
};
183-
if has_valid_element.true_count() == has_valid_element.len() {
184-
return Ok(sums);
185-
}
186-
187-
sums.mask(BoolArray::new(has_valid_element, Validity::NonNullable).into_array())
134+
acc.finish(ctx)
188135
}
189136

190137
#[cfg(test)]

vortex-array/src/stats/expr.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ mod tests {
106106
use crate::expr::stats::Stat;
107107
use crate::scalar::Scalar;
108108
use crate::scalar::ScalarValue;
109-
use crate::validity::Validity;
110109

111110
static SESSION: LazyLock<VortexSession> = LazyLock::new(array_session);
112111

0 commit comments

Comments
 (0)