vortex_array/arrays/listview/vtable/
operator.rs1use std::sync::Arc;
5
6use vortex_error::VortexResult;
7use vortex_vector::listview::ListViewVector;
8
9use crate::ArrayRef;
10use crate::arrays::{ListViewArray, ListViewVTable};
11use crate::execution::{BatchKernelRef, BindCtx, kernel};
12use crate::vtable::{OperatorVTable, ValidityHelper};
13
14impl OperatorVTable<ListViewVTable> for ListViewVTable {
15 fn bind(
16 array: &ListViewArray,
17 selection: Option<&ArrayRef>,
18 ctx: &mut dyn BindCtx,
19 ) -> VortexResult<BatchKernelRef> {
20 let offsets_kernel = ctx.bind(array.offsets(), selection)?;
23 let sizes_kernel = ctx.bind(array.sizes(), selection)?;
24
25 let validity = ctx.bind_validity(array.validity(), array.len(), selection)?;
26
27 let elements_kernel = ctx.bind(array.elements(), None)?;
29
30 Ok(kernel(move || {
31 let offsets = offsets_kernel.execute()?.into_primitive();
32 let sizes = sizes_kernel.execute()?.into_primitive();
33
34 let validity_mask = validity.execute()?;
35
36 let elements = elements_kernel.execute()?;
38
39 Ok(ListViewVector::try_new(Arc::new(elements), offsets, sizes, validity_mask)?.into())
40 }))
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use vortex_dtype::PTypeDowncast;
47 use vortex_mask::Mask;
48 use vortex_vector::VectorOps;
49
50 use crate::IntoArray;
51 use crate::arrays::listview::tests::common::{
52 create_basic_listview, create_nullable_listview, create_overlapping_listview,
53 };
54 use crate::arrays::{ListViewArray, PrimitiveArray};
55 use crate::validity::Validity;
56
57 #[test]
58 fn test_listview_operator_basic() {
59 let listview = create_basic_listview();
62
63 let result = listview.execute().unwrap();
65 assert_eq!(result.len(), 4);
66
67 let listview_vector = result.as_list();
69
70 let offsets = listview_vector.offsets().clone().into_u32();
72 assert_eq!(offsets.elements().as_slice(), &[0, 3, 5, 7]);
73
74 let sizes = listview_vector.sizes().clone().into_u32();
76 assert_eq!(sizes.elements().as_slice(), &[3, 2, 2, 3]);
77
78 let elements = listview_vector.elements().as_primitive().clone().into_i32();
80 assert_eq!(
81 elements.elements().as_slice(),
82 &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
83 );
84
85 assert!(matches!(listview_vector.validity(), Mask::AllTrue(_)));
87 }
88
89 #[test]
90 fn test_listview_operator_with_selection() {
91 let elements =
93 PrimitiveArray::from_iter([10i32, 11, 20, 21, 30, 31, 40, 41, 50, 51, 60, 61])
94 .into_array();
95 let offsets = PrimitiveArray::from_iter([0u32, 2, 4, 6, 8, 10]).into_array();
96 let sizes = PrimitiveArray::from_iter([2u32, 2, 2, 2, 2, 2]).into_array();
97 let listview = ListViewArray::new(elements, offsets, sizes, Validity::AllValid);
98
99 let selection = Mask::from_iter([true, false, true, false, true, false]);
101
102 let result = listview.execute_with_selection(&selection).unwrap();
104
105 assert_eq!(result.len(), 3);
107
108 let listview_vector = result.as_list();
109
110 let offsets = listview_vector.offsets().clone().into_u32();
112 assert_eq!(offsets.elements().as_slice(), &[0, 4, 8]);
113
114 let sizes = listview_vector.sizes().clone().into_u32();
116 assert_eq!(sizes.elements().as_slice(), &[2, 2, 2]);
117
118 let elements = listview_vector.elements().as_primitive().clone().into_i32();
120 assert_eq!(
121 elements.elements().as_slice(),
122 &[10, 11, 20, 21, 30, 31, 40, 41, 50, 51, 60, 61]
123 );
124 }
125
126 #[test]
127 fn test_listview_operator_with_nulls_and_selection() {
128 let listview = create_nullable_listview();
130
131 let selection = Mask::from_iter([true, true, false]);
133
134 let result = listview.execute_with_selection(&selection).unwrap();
136
137 assert_eq!(result.len(), 2);
139
140 let listview_vector = result.as_list();
141
142 let offsets = listview_vector.offsets().clone().into_u32();
144 assert_eq!(offsets.elements().as_slice(), &[0, 2]);
145
146 let sizes = listview_vector.sizes().clone().into_u32();
148 assert_eq!(sizes.elements().as_slice(), &[2, 2]);
149
150 assert!(listview_vector.validity().value(0)); assert!(!listview_vector.validity().value(1)); let elements = listview_vector.elements().as_primitive().clone().into_i32();
156 assert_eq!(elements.elements().as_slice(), &[10, 20, 30, 40, 50]);
157 }
158
159 #[test]
160 fn test_listview_operator_overlapping_with_selection() {
161 let listview = create_overlapping_listview();
163
164 let selection = Mask::from_iter([true, false, true, true, false]);
166
167 let result = listview.execute_with_selection(&selection).unwrap();
169
170 assert_eq!(result.len(), 3);
172
173 let listview_vector = result.as_list();
174
175 let offsets = listview_vector.offsets().clone().into_u32();
177 assert_eq!(offsets.elements().as_slice(), &[5, 8, 0]);
178
179 let sizes = listview_vector.sizes().clone().into_u32();
181 assert_eq!(sizes.elements().as_slice(), &[3, 2, 2]);
182
183 let elements = listview_vector.elements().as_primitive().clone().into_i32();
185 assert_eq!(
186 elements.elements().as_slice(),
187 &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
188 );
189 }
190}