@@ -42,23 +42,27 @@ register_kernel!(SumKernelAdapter(ChunkedVTable).lift());
4242fn sum_int < T : NativePType + PrimInt + FromPrimitiveOrF16 > (
4343 chunks : & [ ArrayRef ] ,
4444) -> VortexResult < Option < T > > {
45- let mut result = T :: zero ( ) ;
45+ let mut result: Option < T > = None ;
4646 for chunk in chunks {
4747 let chunk_sum = sum ( chunk) ?;
4848
4949 let Some ( chunk_sum) = chunk_sum. as_primitive ( ) . as_ :: < T > ( ) else {
50- // Bail out missing statistic
51- return Ok ( None ) ;
52- } ;
53-
54- let Some ( chunk_result) = result. checked_add ( & chunk_sum) else {
55- // Bail out on overflow
56- return Ok ( None ) ;
50+ // Skip missing null chunk
51+ continue ;
5752 } ;
5853
59- result = chunk_result;
54+ result = Some ( match result {
55+ None => chunk_sum,
56+ Some ( result) => {
57+ let Some ( chunk_result) = result. checked_add ( & chunk_sum) else {
58+ // Bail out on overflow
59+ return Ok ( None ) ;
60+ } ;
61+ chunk_result
62+ }
63+ } ) ;
6064 }
61- Ok ( Some ( result) )
65+ Ok ( result)
6266}
6367
6468fn sum_float ( chunks : & [ ArrayRef ] ) -> VortexResult < f64 > {
@@ -179,6 +183,19 @@ mod tests {
179183 assert_eq ! ( result. as_primitive( ) . as_:: <f64 >( ) , Some ( 36.0 ) ) ;
180184 }
181185
186+ #[ test]
187+ fn test_sum_chunked_int_almost_all_null_chunks ( ) {
188+ let chunk1 = PrimitiveArray :: from_option_iter :: < u32 , _ > ( vec ! [ Some ( 1 ) ] ) ;
189+ let chunk2 = PrimitiveArray :: from_option_iter :: < u32 , _ > ( vec ! [ None ] ) ;
190+
191+ let dtype = chunk1. dtype ( ) . clone ( ) ;
192+ let chunked =
193+ ChunkedArray :: try_new ( vec ! [ chunk1. into_array( ) , chunk2. into_array( ) ] , dtype) . unwrap ( ) ;
194+
195+ let result = sum ( chunked. as_ref ( ) ) . unwrap ( ) ;
196+ assert_eq ! ( result. as_primitive( ) . as_:: <u64 >( ) , Some ( 1 ) ) ;
197+ }
198+
182199 #[ test]
183200 fn test_sum_chunked_decimals ( ) {
184201 // Create decimal chunks with precision=10, scale=2
0 commit comments