vortex_array/arrays/null/
mod.rs1use vortex_error::VortexResult;
5use vortex_error::vortex_bail;
6use vortex_error::vortex_ensure;
7use vortex_error::vortex_panic;
8use vortex_session::VortexSession;
9use vortex_session::registry::CachedId;
10
11use crate::ArrayRef;
12use crate::ExecutionCtx;
13use crate::ExecutionResult;
14use crate::array::Array;
15use crate::array::ArrayId;
16use crate::array::ArrayParts;
17use crate::array::ArrayView;
18use crate::array::EmptyArrayData;
19use crate::array::OperationsVTable;
20use crate::array::VTable;
21use crate::array::ValidityVTable;
22use crate::array::with_empty_buffers;
23use crate::arrays::null::compute::rules::PARENT_RULES;
24use crate::buffer::BufferHandle;
25use crate::builders::ArrayBuilder;
26use crate::builders::NullBuilder;
27use crate::dtype::DType;
28use crate::scalar::Scalar;
29use crate::serde::ArrayChildren;
30use crate::validity::Validity;
31
32pub(crate) mod compute;
33
34pub type NullArray = Array<Null>;
36
37impl VTable for Null {
38 type TypedArrayData = EmptyArrayData;
39
40 type OperationsVTable = Self;
41 type ValidityVTable = Self;
42
43 fn id(&self) -> ArrayId {
44 static ID: CachedId = CachedId::new("vortex.null");
45 *ID
46 }
47
48 fn validate(
49 &self,
50 _data: &EmptyArrayData,
51 dtype: &DType,
52 _len: usize,
53 _slots: &[Option<ArrayRef>],
54 ) -> VortexResult<()> {
55 vortex_ensure!(*dtype == DType::Null, "NullArray dtype must be DType::Null");
56 Ok(())
57 }
58
59 fn nbuffers(_array: ArrayView<'_, Self>) -> usize {
60 0
61 }
62
63 fn buffer(_array: ArrayView<'_, Self>, idx: usize) -> BufferHandle {
64 vortex_panic!("NullArray buffer index {idx} out of bounds")
65 }
66
67 fn buffer_name(_array: ArrayView<'_, Self>, _idx: usize) -> Option<String> {
68 None
69 }
70
71 fn with_buffers(
72 &self,
73 array: ArrayView<'_, Self>,
74 buffers: &[BufferHandle],
75 ) -> VortexResult<ArrayParts<Self>> {
76 with_empty_buffers(self, array, buffers)
77 }
78
79 fn slot_name(_array: ArrayView<'_, Self>, idx: usize) -> String {
80 vortex_panic!("NullArray slot_name index {idx} out of bounds")
81 }
82
83 fn serialize(
84 _array: ArrayView<'_, Self>,
85 _session: &VortexSession,
86 ) -> VortexResult<Option<Vec<u8>>> {
87 Ok(Some(vec![]))
88 }
89
90 fn deserialize(
91 &self,
92 dtype: &DType,
93 len: usize,
94 metadata: &[u8],
95
96 _buffers: &[BufferHandle],
97 _children: &dyn ArrayChildren,
98 _session: &VortexSession,
99 ) -> VortexResult<ArrayParts<Self>> {
100 vortex_ensure!(
101 metadata.is_empty(),
102 "NullArray expects empty metadata, got {} bytes",
103 metadata.len()
104 );
105 Ok(ArrayParts::new(
106 self.clone(),
107 dtype.clone(),
108 len,
109 EmptyArrayData,
110 ))
111 }
112
113 fn reduce_parent(
114 array: ArrayView<'_, Self>,
115 parent: &ArrayRef,
116 child_idx: usize,
117 ) -> VortexResult<Option<ArrayRef>> {
118 PARENT_RULES.evaluate(array, parent, child_idx)
119 }
120
121 fn execute(array: Array<Self>, _ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
122 Ok(ExecutionResult::done(array))
123 }
124
125 fn append_to_builder(
126 array: ArrayView<'_, Self>,
127 builder: &mut dyn ArrayBuilder,
128 _ctx: &mut ExecutionCtx,
129 ) -> VortexResult<()> {
130 let Some(builder) = builder.as_any_mut().downcast_mut::<NullBuilder>() else {
131 vortex_bail!("append_to_builder for Null requires a NullBuilder");
132 };
133 builder.append_nulls(array.len());
134 Ok(())
135 }
136}
137
138#[derive(Clone, Debug)]
167pub struct Null;
168
169impl Array<Null> {
170 pub fn new(len: usize) -> Self {
171 unsafe {
172 Array::from_parts_unchecked(ArrayParts::new(Null, DType::Null, len, EmptyArrayData))
173 }
174 }
175}
176
177impl OperationsVTable<Null> for Null {
178 fn scalar_at(
179 _array: ArrayView<'_, Null>,
180 _index: usize,
181 _ctx: &mut ExecutionCtx,
182 ) -> VortexResult<Scalar> {
183 Ok(Scalar::null(DType::Null))
184 }
185}
186
187impl ValidityVTable<Null> for Null {
188 fn validity(_array: ArrayView<'_, Null>) -> VortexResult<Validity> {
189 Ok(Validity::AllInvalid)
190 }
191}