Skip to main content

vortex_array/arrays/null/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::hash::Hash;
5use std::sync::Arc;
6
7use vortex_error::VortexResult;
8use vortex_error::vortex_ensure;
9use vortex_error::vortex_panic;
10use vortex_session::VortexSession;
11
12use crate::ArrayRef;
13use crate::EmptyMetadata;
14use crate::ExecutionCtx;
15use crate::ExecutionResult;
16use crate::Precision;
17use crate::arrays::null::compute::rules::PARENT_RULES;
18use crate::buffer::BufferHandle;
19use crate::dtype::DType;
20use crate::scalar::Scalar;
21use crate::serde::ArrayChildren;
22use crate::stats::ArrayStats;
23use crate::stats::StatsSetRef;
24use crate::validity::Validity;
25use crate::vtable;
26use crate::vtable::Array;
27use crate::vtable::ArrayId;
28use crate::vtable::OperationsVTable;
29use crate::vtable::VTable;
30use crate::vtable::ValidityVTable;
31
32pub(crate) mod compute;
33
34vtable!(Null);
35
36impl VTable for Null {
37    type Array = NullArray;
38
39    type Metadata = EmptyMetadata;
40    type OperationsVTable = Self;
41    type ValidityVTable = Self;
42
43    fn vtable(_array: &Self::Array) -> &Self {
44        &Null
45    }
46
47    fn id(&self) -> ArrayId {
48        Self::ID
49    }
50
51    fn len(array: &NullArray) -> usize {
52        array.len
53    }
54
55    fn dtype(_array: &NullArray) -> &DType {
56        &DType::Null
57    }
58
59    fn stats(array: &NullArray) -> StatsSetRef<'_> {
60        array.stats_set.to_ref(array.as_ref())
61    }
62
63    fn array_hash<H: std::hash::Hasher>(array: &NullArray, state: &mut H, _precision: Precision) {
64        array.len.hash(state);
65    }
66
67    fn array_eq(array: &NullArray, other: &NullArray, _precision: Precision) -> bool {
68        array.len == other.len
69    }
70
71    fn nbuffers(_array: &NullArray) -> usize {
72        0
73    }
74
75    fn buffer(_array: &NullArray, idx: usize) -> BufferHandle {
76        vortex_panic!("NullArray buffer index {idx} out of bounds")
77    }
78
79    fn buffer_name(_array: &NullArray, _idx: usize) -> Option<String> {
80        None
81    }
82
83    fn nchildren(_array: &NullArray) -> usize {
84        0
85    }
86
87    fn child(_array: &NullArray, idx: usize) -> ArrayRef {
88        vortex_panic!("NullArray child index {idx} out of bounds")
89    }
90
91    fn child_name(_array: &NullArray, idx: usize) -> String {
92        vortex_panic!("NullArray child_name index {idx} out of bounds")
93    }
94
95    fn metadata(_array: &NullArray) -> VortexResult<Self::Metadata> {
96        Ok(EmptyMetadata)
97    }
98
99    fn serialize(_metadata: Self::Metadata) -> VortexResult<Option<Vec<u8>>> {
100        Ok(Some(vec![]))
101    }
102
103    fn deserialize(
104        _bytes: &[u8],
105        _dtype: &DType,
106        _len: usize,
107        _buffers: &[BufferHandle],
108        _session: &VortexSession,
109    ) -> VortexResult<Self::Metadata> {
110        Ok(EmptyMetadata)
111    }
112
113    fn build(
114        _dtype: &DType,
115        len: usize,
116        _metadata: &Self::Metadata,
117        _buffers: &[BufferHandle],
118        _children: &dyn ArrayChildren,
119    ) -> VortexResult<NullArray> {
120        Ok(NullArray::new(len))
121    }
122
123    fn with_children(_array: &mut Self::Array, children: Vec<ArrayRef>) -> VortexResult<()> {
124        vortex_ensure!(
125            children.is_empty(),
126            "NullArray has no children, got {}",
127            children.len()
128        );
129        Ok(())
130    }
131
132    fn reduce_parent(
133        array: &Array<Self>,
134        parent: &ArrayRef,
135        child_idx: usize,
136    ) -> VortexResult<Option<ArrayRef>> {
137        PARENT_RULES.evaluate(array, parent, child_idx)
138    }
139
140    fn execute(array: Arc<Array<Self>>, _ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
141        Ok(ExecutionResult::done(array))
142    }
143}
144
145/// A array where all values are null.
146///
147/// This mirrors the Apache Arrow Null array encoding and provides an efficient representation
148/// for arrays containing only null values. No actual data is stored, only the length.
149///
150/// All operations on null arrays return null values or indicate invalid data.
151///
152/// # Examples
153///
154/// ```
155/// # fn main() -> vortex_error::VortexResult<()> {
156/// use vortex_array::arrays::NullArray;
157/// use vortex_array::IntoArray;
158///
159/// // Create a null array with 5 elements
160/// let array = NullArray::new(5);
161///
162/// // Slice the array - still contains nulls
163/// let sliced = array.slice(1..3)?;
164/// assert_eq!(sliced.len(), 2);
165///
166/// // All elements are null
167/// let scalar = array.scalar_at(0).unwrap();
168/// assert!(scalar.is_null());
169/// # Ok(())
170/// # }
171/// ```
172#[derive(Clone, Debug)]
173pub struct NullArray {
174    len: usize,
175    stats_set: ArrayStats,
176}
177
178#[derive(Clone, Debug)]
179pub struct Null;
180
181impl Null {
182    pub const ID: ArrayId = ArrayId::new_ref("vortex.null");
183}
184
185impl NullArray {
186    pub fn new(len: usize) -> Self {
187        Self {
188            len,
189            stats_set: Default::default(),
190        }
191    }
192}
193impl OperationsVTable<Null> for Null {
194    fn scalar_at(
195        _array: &NullArray,
196        _index: usize,
197        _ctx: &mut ExecutionCtx,
198    ) -> VortexResult<Scalar> {
199        Ok(Scalar::null(DType::Null))
200    }
201}
202
203impl ValidityVTable<Null> for Null {
204    fn validity(_array: &NullArray) -> VortexResult<Validity> {
205        Ok(Validity::AllInvalid)
206    }
207}