vortex_sparse/
variants.rs1use vortex_array::variants::{
2 BinaryArrayTrait, BoolArrayTrait, DecimalArrayTrait, ExtensionArrayTrait, ListArrayTrait,
3 NullArrayTrait, PrimitiveArrayTrait, StructArrayTrait, Utf8ArrayTrait,
4};
5use vortex_array::{Array, ArrayVariants, ArrayVariantsImpl};
6use vortex_dtype::FieldName;
7use vortex_error::{VortexExpect, VortexResult, vortex_err};
8use vortex_scalar::StructScalar;
9
10use crate::{ArrayRef, SparseArray};
11
12impl ArrayVariantsImpl for SparseArray {
14 fn _as_null_typed(&self) -> Option<&dyn NullArrayTrait> {
15 Some(self)
16 }
17
18 fn _as_bool_typed(&self) -> Option<&dyn BoolArrayTrait> {
19 Some(self)
20 }
21
22 fn _as_primitive_typed(&self) -> Option<&dyn PrimitiveArrayTrait> {
23 Some(self)
24 }
25
26 fn _as_decimal_typed(&self) -> Option<&dyn DecimalArrayTrait> {
27 Some(self)
28 }
29
30 fn _as_utf8_typed(&self) -> Option<&dyn Utf8ArrayTrait> {
31 Some(self)
32 }
33
34 fn _as_binary_typed(&self) -> Option<&dyn BinaryArrayTrait> {
35 Some(self)
36 }
37
38 fn _as_struct_typed(&self) -> Option<&dyn StructArrayTrait> {
39 Some(self)
40 }
41
42 fn _as_list_typed(&self) -> Option<&dyn ListArrayTrait> {
43 Some(self)
44 }
45
46 fn _as_extension_typed(&self) -> Option<&dyn ExtensionArrayTrait> {
47 Some(self)
48 }
49}
50
51impl NullArrayTrait for SparseArray {}
52
53impl BoolArrayTrait for SparseArray {}
54
55impl PrimitiveArrayTrait for SparseArray {}
56
57impl Utf8ArrayTrait for SparseArray {}
58
59impl BinaryArrayTrait for SparseArray {}
60
61impl DecimalArrayTrait for SparseArray {}
62
63impl StructArrayTrait for SparseArray {
64 fn maybe_null_field_by_idx(&self, idx: usize) -> VortexResult<ArrayRef> {
65 let new_patches = self.patches().clone().map_values(|values| {
66 values
67 .as_struct_typed()
68 .vortex_expect("Expected struct array")
69 .maybe_null_field_by_idx(idx)
70 })?;
71 let scalar = StructScalar::try_from(self.fill_scalar())?.field_by_idx(idx)?;
72
73 Ok(SparseArray::try_new_from_patches(new_patches, scalar)?.into_array())
74 }
75
76 fn project(&self, projection: &[FieldName]) -> VortexResult<ArrayRef> {
77 let new_patches = self.patches().clone().map_values(|values| {
78 values
79 .as_struct_typed()
80 .ok_or_else(|| vortex_err!("Chunk was not a StructArray"))?
81 .project(projection)
82 })?;
83 let scalar = StructScalar::try_from(self.fill_scalar())?.project(projection)?;
84
85 Ok(SparseArray::try_new_from_patches(new_patches, scalar)?.into_array())
86 }
87}
88
89impl ListArrayTrait for SparseArray {}
90
91impl ExtensionArrayTrait for SparseArray {
92 fn storage_data(&self) -> ArrayRef {
93 SparseArray::try_new_from_patches(
94 self.patches()
95 .clone()
96 .map_values(|values| {
97 Ok(values
98 .as_extension_typed()
99 .vortex_expect("Expected extension array")
100 .storage_data())
101 })
102 .vortex_expect("as_extension_array preserves the length"),
103 self.fill_scalar().clone(),
104 )
105 .vortex_expect("Failed to create new sparse array")
106 .into_array()
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use vortex_array::arrays::BoolArray;
113 use vortex_array::compute::invert;
114 use vortex_array::{Array, IntoArray, ToCanonical};
115 use vortex_buffer::buffer;
116 use vortex_scalar::Scalar;
117
118 use crate::SparseArray;
119
120 #[test]
121 fn invert_bools_non_null_fill() {
122 let sparse_bools = SparseArray::try_new(
123 buffer![0u64].into_array(),
124 BoolArray::from_iter([false]).into_array(),
125 2,
126 Scalar::from(true),
127 )
128 .unwrap();
129 let inverted = invert(&sparse_bools).unwrap();
130 assert_eq!(
131 inverted
132 .to_bool()
133 .unwrap()
134 .boolean_buffer()
135 .iter()
136 .collect::<Vec<_>>(),
137 vec![true, false]
138 );
139 }
140}