11// SPDX-License-Identifier: Apache-2.0
22// SPDX-FileCopyrightText: Copyright the Vortex contributors
33
4- use crate :: dtype:: DecimalType ;
54use itertools:: Itertools ;
65use num_traits:: AsPrimitive ;
76use num_traits:: CheckedAdd ;
@@ -15,17 +14,15 @@ use vortex_mask::Mask;
1514
1615use super :: SumState ;
1716use crate :: arrays:: DecimalArray ;
17+ use crate :: dtype:: DecimalDType ;
18+ use crate :: dtype:: DecimalType ;
19+ use crate :: dtype:: NativeDecimalType ;
1820use crate :: match_each_decimal_value_type;
1921use crate :: scalar:: DecimalValue ;
2022
2123/// Accumulate a decimal array into the sum state.
2224/// Returns Ok(true) if saturated (overflow), Ok(false) if not.
23- #[ expect( clippy:: cognitive_complexity) ]
2425pub ( super ) fn accumulate_decimal ( inner : & mut SumState , d : & DecimalArray ) -> VortexResult < bool > {
25- let SumState :: Decimal { value, dtype } = inner else {
26- vortex_panic ! ( "expected decimal sum state for decimal input" ) ;
27- } ;
28-
2926 let mask = d. validity_mask ( ) ?;
3027 let validity = match & mask {
3128 Mask :: AllTrue ( _) => None ,
@@ -35,24 +32,17 @@ pub(super) fn accumulate_decimal(inner: &mut SumState, d: &DecimalArray) -> Vort
3532 }
3633 } ;
3734
35+ let SumState :: Decimal { value, dtype } = inner else {
36+ vortex_panic ! ( "expected decimal sum state for decimal input" ) ;
37+ } ;
38+
3839 let values_type = DecimalType :: smallest_decimal_value_type ( dtype) ;
39- match_each_decimal_value_type ! ( d. values_type( ) , |I | {
40- match_each_decimal_value_type!( values_type, |O | {
41- let initial: O = value
40+ match_each_decimal_value_type ! ( d. values_type( ) , |T | {
41+ match_each_decimal_value_type!( values_type, |I | {
42+ let initial: I = value
4243 . cast( )
4344 . vortex_expect( "cannot fail to cast initial value" ) ;
44-
45- let sum = match validity {
46- Some ( v) => sum_decimal_with_validity( d. buffer:: <I >( ) , v, initial) ,
47- None => sum_decimal( d. buffer:: <I >( ) , initial) ,
48- } ;
49-
50- let decimal_sum = sum
51- . map( DecimalValue :: from)
52- // We have to make sure that the decimal value fits the precision of the decimal dtype.
53- . filter( |v| v. fits_in_precision( * dtype) ) ;
54-
55- match decimal_sum {
45+ match sum_decimal_value( initial, d. buffer:: <T >( ) , validity, * dtype) {
5646 Some ( v) => * value = v,
5747 None => return Ok ( true ) ,
5848 }
@@ -61,6 +51,28 @@ pub(super) fn accumulate_decimal(inner: &mut SumState, d: &DecimalArray) -> Vort
6151 } )
6252}
6353
54+ fn sum_decimal_value < T , I > (
55+ initial : I ,
56+ values : Buffer < T > ,
57+ validity : Option < & BitBuffer > ,
58+ output_dtype : DecimalDType ,
59+ ) -> Option < DecimalValue >
60+ where
61+ T : AsPrimitive < I > ,
62+ I : NumOps + CheckedAdd + Copy + NativeDecimalType + ' static ,
63+ bool : AsPrimitive < I > ,
64+ DecimalValue : From < I > ,
65+ {
66+ let sum = match validity {
67+ Some ( v) => sum_decimal_with_validity ( values, v, initial) ,
68+ None => sum_decimal ( values, initial) ,
69+ } ;
70+
71+ sum. map ( DecimalValue :: from)
72+ // We have to make sure that the decimal value fits the precision of the decimal dtype.
73+ . filter ( |v| v. fits_in_precision ( output_dtype) )
74+ }
75+
6476fn sum_decimal < T : AsPrimitive < I > , I : Copy + CheckedAdd + ' static > (
6577 values : Buffer < T > ,
6678 initial : I ,
0 commit comments