vortex_array/arrays/decimal/
narrow.rs

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