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