vortex_array/arrays/null/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_buffer::ByteBuffer;
5use vortex_dtype::DType;
6use vortex_error::VortexResult;
7use vortex_mask::Mask;
8use vortex_scalar::Scalar;
9
10use crate::serde::ArrayChildren;
11use crate::stats::{ArrayStats, StatsSetRef};
12use crate::vtable::{
13    ArrayVTable, CanonicalVTable, NotSupported, OperationsVTable, SerdeVTable, VTable,
14    ValidityVTable, VisitorVTable,
15};
16use crate::{
17    ArrayBufferVisitor, ArrayChildVisitor, ArrayRef, Canonical, EmptyMetadata, EncodingId,
18    EncodingRef, IntoArray, vtable,
19};
20
21mod compute;
22
23vtable!(Null);
24
25impl VTable for NullVTable {
26    type Array = NullArray;
27    type Encoding = NullEncoding;
28
29    type ArrayVTable = Self;
30    type CanonicalVTable = Self;
31    type OperationsVTable = Self;
32    type ValidityVTable = Self;
33    type VisitorVTable = Self;
34    type ComputeVTable = NotSupported;
35    type EncodeVTable = NotSupported;
36    type PipelineVTable = NotSupported;
37    type SerdeVTable = Self;
38
39    fn id(_encoding: &Self::Encoding) -> EncodingId {
40        EncodingId::new_ref("vortex.null")
41    }
42
43    fn encoding(_array: &Self::Array) -> EncodingRef {
44        EncodingRef::new_ref(NullEncoding.as_ref())
45    }
46}
47
48/// A array where all values are null.
49///
50/// This mirrors the Apache Arrow Null array encoding and provides an efficient representation
51/// for arrays containing only null values. No actual data is stored, only the length.
52///
53/// All operations on null arrays return null values or indicate invalid data.
54///
55/// # Examples
56///
57/// ```
58/// use vortex_array::arrays::NullArray;
59/// use vortex_array::IntoArray;
60///
61/// // Create a null array with 5 elements
62/// let array = NullArray::new(5);
63///
64/// // Slice the array - still contains nulls
65/// let sliced = array.slice(1, 3);
66/// assert_eq!(sliced.len(), 2);
67///
68/// // All elements are null
69/// let scalar = array.scalar_at(0);
70/// assert!(scalar.is_null());
71/// ```
72#[derive(Clone, Debug)]
73pub struct NullArray {
74    len: usize,
75    stats_set: ArrayStats,
76}
77
78#[derive(Clone, Debug)]
79pub struct NullEncoding;
80
81impl NullArray {
82    pub fn new(len: usize) -> Self {
83        Self {
84            len,
85            stats_set: Default::default(),
86        }
87    }
88}
89
90impl ArrayVTable<NullVTable> for NullVTable {
91    fn len(array: &NullArray) -> usize {
92        array.len
93    }
94
95    fn dtype(_array: &NullArray) -> &DType {
96        &DType::Null
97    }
98
99    fn stats(array: &NullArray) -> StatsSetRef<'_> {
100        array.stats_set.to_ref(array.as_ref())
101    }
102}
103
104impl SerdeVTable<NullVTable> for NullVTable {
105    type Metadata = EmptyMetadata;
106
107    fn metadata(_array: &NullArray) -> VortexResult<Option<Self::Metadata>> {
108        Ok(Some(EmptyMetadata))
109    }
110
111    fn build(
112        _encoding: &NullEncoding,
113        _dtype: &DType,
114        len: usize,
115        _metadata: &Self::Metadata,
116        _buffers: &[ByteBuffer],
117        _children: &dyn ArrayChildren,
118    ) -> VortexResult<NullArray> {
119        Ok(NullArray::new(len))
120    }
121}
122
123impl VisitorVTable<NullVTable> for NullVTable {
124    fn visit_buffers(_array: &NullArray, _visitor: &mut dyn ArrayBufferVisitor) {}
125
126    fn visit_children(_array: &NullArray, _visitor: &mut dyn ArrayChildVisitor) {}
127}
128
129impl CanonicalVTable<NullVTable> for NullVTable {
130    fn canonicalize(array: &NullArray) -> VortexResult<Canonical> {
131        Ok(Canonical::Null(array.clone()))
132    }
133}
134
135impl OperationsVTable<NullVTable> for NullVTable {
136    fn slice(_array: &NullArray, start: usize, stop: usize) -> ArrayRef {
137        NullArray::new(stop - start).into_array()
138    }
139
140    fn scalar_at(_array: &NullArray, _index: usize) -> Scalar {
141        Scalar::null(DType::Null)
142    }
143}
144
145impl ValidityVTable<NullVTable> for NullVTable {
146    fn is_valid(_array: &NullArray, _index: usize) -> VortexResult<bool> {
147        Ok(false)
148    }
149
150    fn all_valid(array: &NullArray) -> VortexResult<bool> {
151        Ok(array.is_empty())
152    }
153
154    fn all_invalid(array: &NullArray) -> VortexResult<bool> {
155        Ok(!array.is_empty())
156    }
157
158    fn validity_mask(array: &NullArray) -> VortexResult<Mask> {
159        Ok(Mask::AllFalse(array.len))
160    }
161}