use vortex_buffer::buffer;
use crate::IntoArray;
use crate::arrays::ListView;
use crate::arrays::ListViewArray;
use crate::arrays::PrimitiveArray;
use crate::arrays::StructArray;
use crate::arrays::listview::ListViewArrayExt;
use crate::dtype::DType;
use crate::dtype::FieldNames;
use crate::dtype::Nullability;
use crate::dtype::PType;
use crate::dtype::StructFields;
use crate::validity::Validity;
#[test]
fn test_listview_of_listview_with_overlapping() {
let elements = buffer![1i32, 2, 3, 4, 5, 6, 7, 8].into_array();
let inner_offsets = buffer![0u32, 2, 1, 5, 0, 6].into_array();
let inner_sizes = buffer![3u32, 3, 3, 3, 2, 2].into_array();
let inner_listview =
ListViewArray::new(elements, inner_offsets, inner_sizes, Validity::NonNullable);
let outer_offsets = buffer![0u32, 3].into_array();
let outer_sizes = buffer![3u32, 3].into_array();
let outer_listview = unsafe {
ListViewArray::new_unchecked(
inner_listview.into_array(),
outer_offsets,
outer_sizes,
Validity::NonNullable,
)
.with_zero_copy_to_list(true)
};
assert_eq!(outer_listview.len(), 2);
let first_outer = outer_listview.list_elements_at(0).unwrap();
let first_outer_lv = first_outer.as_::<ListView>();
assert_eq!(first_outer_lv.len(), 3);
let inner0 = first_outer_lv.list_elements_at(0).unwrap();
let inner1 = first_outer_lv.list_elements_at(1).unwrap();
assert_eq!(
inner0
.scalar_at(0)
.unwrap()
.as_primitive()
.as_::<i32>()
.unwrap(),
1
);
assert_eq!(
inner0
.scalar_at(2)
.unwrap()
.as_primitive()
.as_::<i32>()
.unwrap(),
3
);
assert_eq!(
inner1
.scalar_at(0)
.unwrap()
.as_primitive()
.as_::<i32>()
.unwrap(),
3
);
assert_eq!(
inner1
.scalar_at(1)
.unwrap()
.as_primitive()
.as_::<i32>()
.unwrap(),
4
);
let sliced = outer_listview.slice(1..2).unwrap();
assert_eq!(sliced.len(), 1);
let sliced_lv = sliced.as_::<ListView>();
let inner_after_slice = sliced_lv.list_elements_at(0).unwrap();
assert_eq!(inner_after_slice.len(), 3);
}
#[test]
fn test_deeply_nested_out_of_order() {
let elements = buffer![1i32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16].into_array();
let l1_offsets = buffer![8u32, 0, 4, 12, 2, 10, 6, 14].into_array();
let l1_sizes = buffer![2u32, 2, 2, 2, 2, 2, 2, 2].into_array();
let level1 = ListViewArray::new(elements, l1_offsets, l1_sizes, Validity::NonNullable);
let l2_offsets = buffer![6u32, 2, 0, 4].into_array();
let l2_sizes = buffer![2u32, 2, 2, 2].into_array();
let level2 = ListViewArray::new(
level1.into_array(),
l2_offsets,
l2_sizes,
Validity::NonNullable,
);
let l3_offsets = buffer![2u32, 0].into_array();
let l3_sizes = buffer![2u32, 2].into_array();
let level3 = ListViewArray::new(
level2.into_array(),
l3_offsets,
l3_sizes,
Validity::NonNullable,
);
assert_eq!(level3.len(), 2);
let top0 = level3.list_elements_at(0).unwrap();
let top0_lv = top0.as_::<ListView>();
assert_eq!(top0_lv.len(), 2);
let mid0 = top0_lv.list_elements_at(0).unwrap();
let mid0_lv = mid0.as_::<ListView>();
assert_eq!(mid0_lv.len(), 2);
let inner = mid0_lv.list_elements_at(0).unwrap();
assert_eq!(inner.len(), 2);
let sliced = level3.slice(0..1).unwrap();
assert_eq!(sliced.len(), 1);
}
#[test]
fn test_mixed_offset_size_types() {
let elements = PrimitiveArray::from_iter(0i32..256).into_array();
let inner_offsets = buffer![0u32, 10, 20, 30, 40, 50, 100, 150, 200].into_array();
let inner_sizes = buffer![5u16, 8, 10, 7, 15, 20, 25, 30, 50].into_array();
let inner_listview =
ListViewArray::new(elements, inner_offsets, inner_sizes, Validity::NonNullable);
let outer_offsets = buffer![0u64, 3, 6].into_array();
let outer_sizes = buffer![3u8, 3, 3].into_array();
let outer_listview = ListViewArray::new(
inner_listview.into_array(),
outer_offsets,
outer_sizes,
Validity::NonNullable,
);
assert_eq!(outer_listview.len(), 3);
let first_outer = outer_listview.list_elements_at(0).unwrap();
assert_eq!(first_outer.len(), 3);
let sliced = outer_listview.slice(1..3).unwrap();
assert_eq!(sliced.len(), 2);
let sliced_lv = sliced.as_::<ListView>();
let sliced_first = sliced_lv.list_elements_at(0).unwrap();
assert_eq!(sliced_first.len(), 3);
}
#[test]
fn test_listview_zero_and_overlapping() {
let elements = buffer![1i32, 2, 3, 4, 5].into_array();
let inner_offsets = buffer![0u32, 0, 3, 1, 4, 0, 0, 2].into_array();
let inner_sizes = buffer![0u32, 3, 0, 3, 1, 0, 5, 0].into_array();
let inner_listview =
ListViewArray::new(elements, inner_offsets, inner_sizes, Validity::NonNullable);
let outer_offsets = buffer![0u32, 3, 6].into_array();
let outer_sizes = buffer![3u32, 3, 2].into_array();
let outer_listview = ListViewArray::new(
inner_listview.into_array(),
outer_offsets,
outer_sizes,
Validity::NonNullable,
);
assert_eq!(outer_listview.len(), 3);
let first_outer = outer_listview.list_elements_at(0).unwrap();
let first_outer_lv = first_outer.as_::<ListView>();
let inner0 = first_outer_lv.list_elements_at(0).unwrap();
assert_eq!(inner0.len(), 0);
let inner1 = first_outer_lv.list_elements_at(1).unwrap();
assert_eq!(inner1.len(), 3); assert_eq!(
inner1
.scalar_at(0)
.unwrap()
.as_primitive()
.as_::<i32>()
.unwrap(),
1
);
let inner2 = first_outer_lv.list_elements_at(2).unwrap();
assert_eq!(inner2.len(), 0);
let second_outer = outer_listview.list_elements_at(1).unwrap();
let second_outer_lv = second_outer.as_::<ListView>();
let inner3 = second_outer_lv.list_elements_at(0).unwrap();
assert_eq!(inner3.len(), 3); assert_eq!(
inner3
.scalar_at(0)
.unwrap()
.as_primitive()
.as_::<i32>()
.unwrap(),
2
);
let sliced = outer_listview.slice(0..2).unwrap();
assert_eq!(sliced.len(), 2);
}
#[test]
fn test_listview_of_struct_with_nulls() {
let struct_fields = StructFields::new(
FieldNames::from(["id", "value"].as_slice()),
vec![
DType::Primitive(PType::U32, Nullability::NonNullable),
DType::Primitive(PType::F64, Nullability::Nullable),
],
);
let id_values = buffer![1u32, 2, 3, 4, 5, 6].into_array();
let value_values = PrimitiveArray::from_option_iter(vec![
Some(1.1f64),
None,
Some(3.3),
Some(4.4),
None,
Some(6.6),
])
.into_array();
let struct_validity = Validity::from_iter([true, true, false, true, true, false]);
let struct_array = StructArray::try_new(
struct_fields.names().clone(),
vec![id_values, value_values],
6,
struct_validity,
)
.unwrap();
let offsets = buffer![0u32, 1, 3].into_array();
let sizes = buffer![2u32, 3, 3].into_array();
let listview = ListViewArray::new(
struct_array.into_array(),
offsets,
sizes,
Validity::NonNullable,
);
assert_eq!(listview.len(), 3);
let list0 = listview.list_elements_at(0).unwrap();
assert_eq!(list0.len(), 2);
let list1 = listview.list_elements_at(1).unwrap();
assert_eq!(list1.len(), 3);
assert!(list1.scalar_at(1).unwrap().is_null());
let sliced = listview.slice(1..3).unwrap();
assert_eq!(sliced.len(), 2);
}