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