Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-compute/src/cast/dictionary_to.rs
6939 views
1
use arrow::array::{Array, DictionaryArray, DictionaryKey};
2
use arrow::datatypes::ArrowDataType;
3
use arrow::match_integer_type;
4
use polars_error::{PolarsResult, polars_bail};
5
6
use super::{CastOptionsImpl, cast, primitive_to_primitive};
7
8
macro_rules! key_cast {
9
($keys:expr, $values:expr, $array:expr, $to_keys_type:expr, $to_type:ty, $to_datatype:expr) => {{
10
let cast_keys = primitive_to_primitive::<_, $to_type>($keys, $to_keys_type);
11
12
// Failure to cast keys (because they don't fit in the
13
// target type) results in NULL values;
14
if cast_keys.null_count() > $keys.null_count() {
15
polars_bail!(ComputeError: "overflow")
16
}
17
// SAFETY: this is safe because given a type `T` that fits in a `usize`, casting it to type `P` either overflows or also fits in a `usize`
18
unsafe {
19
DictionaryArray::try_new_unchecked($to_datatype, cast_keys, $values.clone())
20
}
21
.map(|x| x.boxed())
22
}};
23
}
24
25
pub(super) fn dictionary_cast_dyn<K: DictionaryKey + num_traits::NumCast>(
26
array: &dyn Array,
27
to_type: &ArrowDataType,
28
options: CastOptionsImpl,
29
) -> PolarsResult<Box<dyn Array>> {
30
let array = array.as_any().downcast_ref::<DictionaryArray<K>>().unwrap();
31
let keys = array.keys();
32
let values = array.values();
33
34
match to_type {
35
ArrowDataType::Dictionary(to_keys_type, to_values_type, _) => {
36
let values = cast(values.as_ref(), to_values_type, options)?;
37
38
// create the appropriate array type
39
let to_key_type = (*to_keys_type).into();
40
41
// SAFETY:
42
// we return an error on overflow so the integers remain within bounds
43
match_integer_type!(to_keys_type, |$T| {
44
key_cast!(keys, values, array, &to_key_type, $T, to_type.clone())
45
})
46
},
47
_ => unimplemented!(),
48
}
49
}
50
51