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