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