vortex_array/builders/
null.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::any::Any;
5
6use vortex_dtype::DType;
7use vortex_error::{VortexResult, vortex_ensure};
8use vortex_mask::Mask;
9use vortex_scalar::Scalar;
10
11use crate::arrays::NullArray;
12use crate::builders::ArrayBuilder;
13use crate::canonical::Canonical;
14use crate::{Array, ArrayRef, IntoArray};
15
16/// The builder for building a [`NullArray`].
17pub struct NullBuilder {
18    length: usize,
19}
20
21impl Default for NullBuilder {
22    fn default() -> Self {
23        Self::new()
24    }
25}
26
27impl NullBuilder {
28    pub fn new() -> Self {
29        Self { length: 0 }
30    }
31}
32
33impl ArrayBuilder for NullBuilder {
34    fn as_any(&self) -> &dyn Any {
35        self
36    }
37
38    fn as_any_mut(&mut self) -> &mut dyn Any {
39        self
40    }
41
42    fn dtype(&self) -> &DType {
43        &DType::Null
44    }
45
46    fn len(&self) -> usize {
47        self.length
48    }
49
50    fn append_zeros(&mut self, n: usize) {
51        self.length += n;
52    }
53
54    unsafe fn append_nulls_unchecked(&mut self, n: usize) {
55        self.length += n;
56    }
57
58    fn append_scalar(&mut self, scalar: &Scalar) -> VortexResult<()> {
59        vortex_ensure!(
60            scalar.dtype() == self.dtype(),
61            "NullBuilder expected scalar with dtype {:?}, got {:?}",
62            self.dtype(),
63            scalar.dtype()
64        );
65
66        self.append_null();
67        Ok(())
68    }
69
70    unsafe fn extend_from_array_unchecked(&mut self, array: &dyn Array) {
71        self.append_nulls(array.len());
72    }
73
74    fn ensure_capacity(&mut self, _capacity: usize) {}
75
76    fn set_validity(&mut self, validity: Mask) {
77        self.length = validity.len();
78    }
79
80    fn finish(&mut self) -> ArrayRef {
81        NullArray::new(self.length).into_array()
82    }
83
84    fn finish_into_canonical(&mut self) -> Canonical {
85        Canonical::Null(NullArray::new(self.length))
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use vortex_dtype::DType;
92    use vortex_scalar::Scalar;
93
94    use super::*;
95    use crate::builders::ArrayBuilder;
96
97    #[test]
98    fn test_append_scalar() {
99        let mut builder = NullBuilder::new();
100
101        // Test appending null scalar.
102        let null_scalar = Scalar::null(DType::Null);
103        builder.append_scalar(&null_scalar).unwrap();
104        builder.append_scalar(&null_scalar).unwrap();
105        builder.append_scalar(&null_scalar).unwrap();
106
107        let array = builder.finish();
108        assert_eq!(array.len(), 3);
109
110        // For null arrays, all values are null - nothing to check for actual values.
111        // Just verify the array is indeed a null array with the right length.
112
113        // Test wrong dtype error.
114        let mut builder = NullBuilder::new();
115        let wrong_scalar = Scalar::from(42i32);
116        assert!(builder.append_scalar(&wrong_scalar).is_err());
117    }
118}