Skip to main content

vortex_array/arrays/decimal/
utils.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use itertools::Itertools;
5use itertools::MinMaxResult;
6use vortex_error::VortexExpect;
7
8use crate::arrays::DecimalArray;
9use crate::dtype::DecimalType;
10use crate::dtype::i256;
11
12macro_rules! try_downcast {
13    ($array:expr, from: $src:ty, to: $($dst:ty),*) => {{
14        use crate::dtype::BigCast;
15
16        // Collect the min/max of the values
17        let minmax = $array.buffer::<$src>().iter().copied().minmax();
18        match minmax {
19            MinMaxResult::NoElements => return $array,
20            MinMaxResult::OneElement(_) => return $array,
21            MinMaxResult::MinMax(min, max) => {
22                $(
23                    if <$dst as BigCast>::from(min).is_some() && <$dst as BigCast>::from(max).is_some() {
24                        return DecimalArray::new::<$dst>(
25                            $array
26                                .buffer::<$src>()
27                                .into_iter()
28                                .map(|v| <$dst as BigCast>::from(v).vortex_expect("decimal conversion failure"))
29                                .collect(),
30                            $array.decimal_dtype(),
31                            $array
32                                .validity()
33                                .vortex_expect("decimal validity should be derivable"),
34                        );
35                    }
36                )*
37
38                return $array;
39            }
40        }
41    }};
42}
43
44/// Attempt to narrow the decimal array to any smaller supported type.
45pub fn narrowed_decimal(decimal_array: DecimalArray) -> DecimalArray {
46    match decimal_array.values_type() {
47        // Cannot narrow any more
48        DecimalType::I8 => decimal_array,
49        DecimalType::I16 => {
50            try_downcast!(decimal_array, from: i16, to: i8)
51        }
52        DecimalType::I32 => {
53            try_downcast!(decimal_array, from: i32, to: i8, i16)
54        }
55        DecimalType::I64 => {
56            try_downcast!(decimal_array, from: i64, to: i8, i16, i32)
57        }
58        DecimalType::I128 => {
59            try_downcast!(decimal_array, from: i128, to: i8, i16, i32, i64)
60        }
61        DecimalType::I256 => {
62            try_downcast!(decimal_array, from: i256, to: i8, i16, i32, i64, i128)
63        }
64    }
65}