@@ -10,7 +10,7 @@ use paste::paste;
1010use crate :: decimal:: max_precision:: {
1111 MAX_DECIMAL256_FOR_EACH_PRECISION , MIN_DECIMAL256_FOR_EACH_PRECISION ,
1212} ;
13- use crate :: { BigCast , i256} ;
13+ use crate :: { BigCast , DecimalDType , i256} ;
1414
1515/// Type of the decimal values.
1616///
@@ -35,6 +35,27 @@ pub enum DecimalType {
3535 I256 = 5 ,
3636}
3737
38+ impl DecimalType {
39+ /// Maps a `DecimalDType` (precision) into the smallest `DecimalType` that can represent it.
40+ pub fn smallest_decimal_value_type ( decimal_dtype : & DecimalDType ) -> DecimalType {
41+ match decimal_dtype. precision ( ) {
42+ 1 ..=2 => DecimalType :: I8 ,
43+ 3 ..=4 => DecimalType :: I16 ,
44+ 5 ..=9 => DecimalType :: I32 ,
45+ 10 ..=18 => DecimalType :: I64 ,
46+ 19 ..=38 => DecimalType :: I128 ,
47+ 39 ..=76 => DecimalType :: I256 ,
48+ 0 => unreachable ! ( "precision must be greater than 0" ) ,
49+ p => unreachable ! ( "precision larger than 76 is invalid found precision {p}" ) ,
50+ }
51+ }
52+
53+ /// True if `Self` can represent every value of the type `DecimalDType`.
54+ pub fn is_compatible_decimal_value_type ( self , dtype : DecimalDType ) -> bool {
55+ self >= Self :: smallest_decimal_value_type ( & dtype)
56+ }
57+ }
58+
3859/// Type of decimal scalar values.
3960///
4061/// This trait is implemented by native integer types that can be used to store decimal values.
@@ -61,8 +82,11 @@ pub trait NativeDecimalType:
6182 const MAX_SCALE : i8 ;
6283
6384 /// The minimum value for each precision supported by this decimal type.
85+ /// This is an array of length `MAX_PRECISION + 1` where the `i`th element is the minimum value
86+ /// for a precision of `i` (including precision 0).
6487 const MIN_BY_PRECISION : & ' static [ Self ] ;
6588 /// The maximum value for each precision supported by this decimal type.
89+ /// similar to `MIN_BY_PRECISION`.
6690 const MAX_BY_PRECISION : & ' static [ Self ] ;
6791
6892 /// Downcast the provided object to a type-specific instance.
@@ -127,24 +151,24 @@ macro_rules! impl_decimal {
127151 const MAX_SCALE : i8 = Self :: MAX_PRECISION as i8 ;
128152
129153 const MIN_BY_PRECISION : & ' static [ Self ] = & {
130- let mut mins = [ $T:: ZERO ; Self :: MAX_PRECISION as usize ] ;
154+ let mut mins = [ $T:: ZERO ; Self :: MAX_PRECISION as usize + 1 ] ;
131155 let mut p = $T:: ONE ;
132156 let mut i = 0 ;
133157 while i < Self :: MAX_PRECISION as usize {
134158 p = p * 10 ;
135- mins[ i] = -( p - 1 ) ;
159+ mins[ i + 1 ] = -( p - 1 ) ;
136160 i += 1 ;
137161 }
138162 mins
139163 } ;
140164
141165 const MAX_BY_PRECISION : & ' static [ Self ] = & {
142- let mut maxs = [ $T:: ZERO ; Self :: MAX_PRECISION as usize ] ;
166+ let mut maxs = [ $T:: ZERO ; Self :: MAX_PRECISION as usize + 1 ] ;
143167 let mut p = $T:: ONE ;
144168 let mut i = 0 ;
145169 while i < Self :: MAX_PRECISION as usize {
146170 p = p * 10 ;
147- maxs[ i] = p - 1 ;
171+ maxs[ i + 1 ] = p - 1 ;
148172 i += 1 ;
149173 }
150174 maxs
0 commit comments