Skip to content

Commit 3e02689

Browse files
authored
Add time dictionary coercions (#6208)
* Add time dictionary coercions * format * Pass through primitive values
1 parent 79ffdc4 commit 3e02689

2 files changed

Lines changed: 89 additions & 0 deletions

File tree

arrow-cast/src/cast/dictionary.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,26 @@ where
162162
take(cast_dict_values.as_ref(), dict_array.keys(), None)
163163
}
164164

165+
/// Pack a data type into a dictionary array passing the values through a primitive array
166+
pub(crate) fn pack_array_to_dictionary_via_primitive<K: ArrowDictionaryKeyType>(
167+
array: &dyn Array,
168+
primitive_type: DataType,
169+
dict_value_type: &DataType,
170+
cast_options: &CastOptions,
171+
) -> Result<ArrayRef, ArrowError> {
172+
let primitive = cast_with_options(array, &primitive_type, cast_options)?;
173+
let dict = cast_with_options(
174+
primitive.as_ref(),
175+
&DataType::Dictionary(Box::new(K::DATA_TYPE), Box::new(primitive_type)),
176+
cast_options,
177+
)?;
178+
cast_with_options(
179+
dict.as_ref(),
180+
&DataType::Dictionary(Box::new(K::DATA_TYPE), Box::new(dict_value_type.clone())),
181+
cast_options,
182+
)
183+
}
184+
165185
/// Attempts to encode an array into an `ArrayDictionary` with index
166186
/// type K and value (dictionary) type value_type
167187
///
@@ -188,6 +208,45 @@ pub(crate) fn cast_to_dictionary<K: ArrowDictionaryKeyType>(
188208
Decimal256(_, _) => {
189209
pack_numeric_to_dictionary::<K, Decimal256Type>(array, dict_value_type, cast_options)
190210
}
211+
Float16 => {
212+
pack_numeric_to_dictionary::<K, Float16Type>(array, dict_value_type, cast_options)
213+
}
214+
Float32 => {
215+
pack_numeric_to_dictionary::<K, Float32Type>(array, dict_value_type, cast_options)
216+
}
217+
Float64 => {
218+
pack_numeric_to_dictionary::<K, Float64Type>(array, dict_value_type, cast_options)
219+
}
220+
Date32 => pack_array_to_dictionary_via_primitive::<K>(
221+
array,
222+
DataType::Int32,
223+
dict_value_type,
224+
cast_options,
225+
),
226+
Date64 => pack_array_to_dictionary_via_primitive::<K>(
227+
array,
228+
DataType::Int64,
229+
dict_value_type,
230+
cast_options,
231+
),
232+
Time32(_) => pack_array_to_dictionary_via_primitive::<K>(
233+
array,
234+
DataType::Int32,
235+
dict_value_type,
236+
cast_options,
237+
),
238+
Time64(_) => pack_array_to_dictionary_via_primitive::<K>(
239+
array,
240+
DataType::Int64,
241+
dict_value_type,
242+
cast_options,
243+
),
244+
Timestamp(_, _) => pack_array_to_dictionary_via_primitive::<K>(
245+
array,
246+
DataType::Int64,
247+
dict_value_type,
248+
cast_options,
249+
),
191250
Utf8 => {
192251
// If the input is a view type, we can avoid casting (thus copying) the data
193252
if array.data_type() == &DataType::Utf8View {

arrow-cast/src/cast/mod.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6768,6 +6768,36 @@ mod tests {
67686768
assert_eq!(array_to_strings(&cast_array), expected);
67696769
}
67706770

6771+
#[test]
6772+
fn test_cast_time_array_to_dict() {
6773+
use DataType::*;
6774+
6775+
let array = Arc::new(Date32Array::from(vec![Some(1000), None, Some(2000)])) as ArrayRef;
6776+
6777+
let expected = vec!["1972-09-27", "null", "1975-06-24"];
6778+
6779+
let cast_type = Dictionary(Box::new(UInt8), Box::new(Date32));
6780+
let cast_array = cast(&array, &cast_type).expect("cast failed");
6781+
assert_eq!(cast_array.data_type(), &cast_type);
6782+
assert_eq!(array_to_strings(&cast_array), expected);
6783+
}
6784+
6785+
#[test]
6786+
fn test_cast_timestamp_array_to_dict() {
6787+
use DataType::*;
6788+
6789+
let array = Arc::new(
6790+
TimestampSecondArray::from(vec![Some(1000), None, Some(2000)]).with_timezone_utc(),
6791+
) as ArrayRef;
6792+
6793+
let expected = vec!["1970-01-01T00:16:40", "null", "1970-01-01T00:33:20"];
6794+
6795+
let cast_type = Dictionary(Box::new(UInt8), Box::new(Timestamp(TimeUnit::Second, None)));
6796+
let cast_array = cast(&array, &cast_type).expect("cast failed");
6797+
assert_eq!(cast_array.data_type(), &cast_type);
6798+
assert_eq!(array_to_strings(&cast_array), expected);
6799+
}
6800+
67716801
#[test]
67726802
fn test_cast_string_array_to_dict() {
67736803
use DataType::*;

0 commit comments

Comments
 (0)