1use crate::{bitmap::Bitmap, datatypes::DataType};
2use std::any::Any;
3
4use crate::array::MutableArray;
5use crate::bitmap::MutableBitmap;
6use crate::{
7 array::{Array, FromFfi, ToFfi},
8 datatypes::PhysicalType,
9 error::Error,
10 ffi,
11};
12
13#[derive(Clone)]
15pub struct NullArray {
16 data_type: DataType,
17 length: usize,
18}
19
20impl NullArray {
21 pub fn try_new(data_type: DataType, length: usize) -> Result<Self, Error> {
26 if data_type.to_physical_type() != PhysicalType::Null {
27 return Err(Error::oos(
28 "NullArray can only be initialized with a DataType whose physical type is Boolean",
29 ));
30 }
31
32 Ok(Self { data_type, length })
33 }
34
35 pub fn new(data_type: DataType, length: usize) -> Self {
40 Self::try_new(data_type, length).unwrap()
41 }
42
43 pub fn new_empty(data_type: DataType) -> Self {
45 Self::new(data_type, 0)
46 }
47
48 pub fn new_null(data_type: DataType, length: usize) -> Self {
50 Self::new(data_type, length)
51 }
52
53 impl_sliced!();
54 impl_into_array!();
55}
56
57impl NullArray {
58 pub fn slice(&mut self, offset: usize, length: usize) {
62 assert!(
63 offset + length <= self.len(),
64 "the offset of the new array cannot exceed the arrays' length"
65 );
66 unsafe { self.slice_unchecked(offset, length) };
67 }
68
69 pub unsafe fn slice_unchecked(&mut self, _offset: usize, length: usize) {
73 self.length = length;
74 }
75
76 #[inline]
77 fn len(&self) -> usize {
78 self.length
79 }
80}
81
82impl Array for NullArray {
83 impl_common_array!();
84
85 fn validity(&self) -> Option<&Bitmap> {
86 None
87 }
88
89 fn with_validity(&self, _: Option<Bitmap>) -> Box<dyn Array> {
90 panic!("cannot set validity of a null array")
91 }
92}
93
94#[derive(Debug)]
95pub struct MutableNullArray {
98 inner: NullArray,
99}
100
101impl MutableNullArray {
102 pub fn new(data_type: DataType, length: usize) -> Self {
107 let inner = NullArray::try_new(data_type, length).unwrap();
108 Self { inner }
109 }
110}
111
112impl From<MutableNullArray> for NullArray {
113 fn from(value: MutableNullArray) -> Self {
114 value.inner
115 }
116}
117
118impl MutableArray for MutableNullArray {
119 fn data_type(&self) -> &DataType {
120 &DataType::Null
121 }
122
123 fn len(&self) -> usize {
124 self.inner.length
125 }
126
127 fn validity(&self) -> Option<&MutableBitmap> {
128 None
129 }
130
131 fn as_box(&mut self) -> Box<dyn Array> {
132 self.inner.clone().boxed()
133 }
134
135 fn as_any(&self) -> &dyn Any {
136 self
137 }
138
139 fn as_mut_any(&mut self) -> &mut dyn Any {
140 self
141 }
142
143 fn push_null(&mut self) {
144 self.inner.length += 1;
145 }
146
147 fn reserve(&mut self, _additional: usize) {
148 }
150
151 fn shrink_to_fit(&mut self) {
152 }
154}
155
156impl std::fmt::Debug for NullArray {
157 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
158 write!(f, "NullArray({})", self.len())
159 }
160}
161
162unsafe impl ToFfi for NullArray {
163 fn buffers(&self) -> Vec<Option<*const u8>> {
164 vec![None]
167 }
168
169 fn offset(&self) -> Option<usize> {
170 Some(0)
171 }
172
173 fn to_ffi_aligned(&self) -> Self {
174 self.clone()
175 }
176}
177
178impl<A: ffi::ArrowArrayRef> FromFfi<A> for NullArray {
179 unsafe fn try_from_ffi(array: A) -> Result<Self, Error> {
180 let data_type = array.data_type().clone();
181 Self::try_new(data_type, array.array().len())
182 }
183}
184
185#[cfg(feature = "arrow")]
186mod arrow {
187 use super::*;
188 use arrow_data::{ArrayData, ArrayDataBuilder};
189 impl NullArray {
190 pub fn to_data(&self) -> ArrayData {
192 let builder = ArrayDataBuilder::new(arrow_schema::DataType::Null).len(self.len());
193
194 unsafe { builder.build_unchecked() }
196 }
197
198 pub fn from_data(data: &ArrayData) -> Self {
200 Self::new(DataType::Null, data.len())
201 }
202 }
203}