Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
feat: Support cast to large list. (#1547)
Browse files Browse the repository at this point in the history
  • Loading branch information
reswqa committed Aug 20, 2023
1 parent 2b3e2a9 commit 3d7d9ac
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/compute/cast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ pub fn can_cast_types(from_type: &DataType, to_type: &DataType) -> bool {
(List(list_from), LargeList(list_to)) if list_from == list_to => true,
(LargeList(list_from), List(list_to)) if list_from == list_to => true,
(_, List(list_to)) => can_cast_types(from_type, &list_to.data_type),
(_, LargeList(list_to)) => can_cast_types(from_type, &list_to.data_type),
(Dictionary(_, from_value_type, _), Dictionary(_, to_value_type, _)) => {
can_cast_types(from_value_type, to_value_type)
}
Expand Down Expand Up @@ -509,6 +510,19 @@ pub fn cast(array: &dyn Array, to_type: &DataType, options: CastOptions) -> Resu
Ok(Box::new(list_array))
}

(_, LargeList(to)) => {
// cast primitive to list's primitive
let values = cast(array, &to.data_type, options)?;
// create offsets, where if array.len() = 2, we have [0,1,2]
let offsets = (0..=array.len() as i64).collect::<Vec<_>>();
// Safety: offsets _are_ monotonically increasing
let offsets = unsafe { Offsets::new_unchecked(offsets) };

let list_array = ListArray::<i64>::new(to_type.clone(), offsets.into(), values, None);

Ok(Box::new(list_array))
}

(Dictionary(index_type, ..), _) => match_integer_type!(index_type, |$T| {
dictionary_cast_dyn::<$T>(array, to_type, options)
}),
Expand Down
23 changes: 23 additions & 0 deletions tests/it/compute/cast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use arrow2::array::*;
use arrow2::compute::cast::{can_cast_types, cast, CastOptions};
use arrow2::datatypes::DataType::LargeList;
use arrow2::datatypes::*;
use arrow2::types::{days_ms, months_days_ns, NativeType};

Expand Down Expand Up @@ -120,6 +121,28 @@ fn i32_to_i32() {
assert_eq!(c, &expected);
}

#[test]
fn i32_to_large_list_i32() {
let array = Int32Array::from_slice([5, 6, 7, 8, 9]);
let b = cast(
&array,
&LargeList(Box::new(Field::new("item", DataType::Int32, true))),
CastOptions::default(),
)
.unwrap();

let arr = b.as_any().downcast_ref::<ListArray<i64>>().unwrap();
assert_eq!(&[0, 1, 2, 3, 4, 5], arr.offsets().as_slice());
let values = arr.values();
let c = values
.as_any()
.downcast_ref::<PrimitiveArray<i32>>()
.unwrap();

let expected = Int32Array::from_slice([5, 6, 7, 8, 9]);
assert_eq!(c, &expected);
}

#[test]
fn i32_to_list_i32() {
let array = Int32Array::from_slice([5, 6, 7, 8, 9]);
Expand Down

0 comments on commit 3d7d9ac

Please sign in to comment.