arrow_array/array/
null_array.rs1use crate::builder::NullBuilder;
21use crate::{Array, ArrayRef};
22use arrow_buffer::buffer::NullBuffer;
23use arrow_data::{ArrayData, ArrayDataBuilder};
24use arrow_schema::DataType;
25use std::any::Any;
26use std::sync::Arc;
27
28#[derive(Clone)]
46pub struct NullArray {
47 len: usize,
48}
49
50impl NullArray {
51 pub fn new(length: usize) -> Self {
57 Self { len: length }
58 }
59
60 pub fn slice(&self, offset: usize, len: usize) -> Self {
65 assert!(
66 offset.saturating_add(len) <= self.len,
67 "the length + offset of the sliced BooleanBuffer cannot exceed the existing length"
68 );
69
70 Self { len }
71 }
72
73 pub fn builder(_capacity: usize) -> NullBuilder {
78 NullBuilder::new()
79 }
80}
81
82unsafe impl Array for NullArray {
84 fn as_any(&self) -> &dyn Any {
85 self
86 }
87
88 fn to_data(&self) -> ArrayData {
89 self.clone().into()
90 }
91
92 fn into_data(self) -> ArrayData {
93 self.into()
94 }
95
96 fn data_type(&self) -> &DataType {
97 &DataType::Null
98 }
99
100 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
101 Arc::new(self.slice(offset, length))
102 }
103
104 fn len(&self) -> usize {
105 self.len
106 }
107
108 fn is_empty(&self) -> bool {
109 self.len == 0
110 }
111
112 fn offset(&self) -> usize {
113 0
114 }
115
116 fn nulls(&self) -> Option<&NullBuffer> {
117 None
118 }
119
120 fn logical_nulls(&self) -> Option<NullBuffer> {
121 (self.len != 0).then(|| NullBuffer::new_null(self.len))
122 }
123
124 fn is_nullable(&self) -> bool {
125 !self.is_empty()
126 }
127
128 fn logical_null_count(&self) -> usize {
129 self.len
130 }
131
132 fn get_buffer_memory_size(&self) -> usize {
133 0
134 }
135
136 fn get_array_memory_size(&self) -> usize {
137 std::mem::size_of::<Self>()
138 }
139
140 #[cfg(feature = "pool")]
141 fn claim(&self, _pool: &dyn arrow_buffer::MemoryPool) {
142 }
144}
145
146impl From<ArrayData> for NullArray {
147 fn from(data: ArrayData) -> Self {
148 let (data_type, len, nulls, _offset, buffers, _child_data) = data.into_parts();
149
150 assert_eq!(
151 data_type,
152 DataType::Null,
153 "NullArray data type should be Null"
154 );
155 assert_eq!(buffers.len(), 0, "NullArray data should contain 0 buffers");
156 assert!(
157 nulls.is_none(),
158 "NullArray data should not contain a null buffer, as no buffers are required"
159 );
160 Self { len }
161 }
162}
163
164impl From<NullArray> for ArrayData {
165 fn from(array: NullArray) -> Self {
166 let builder = ArrayDataBuilder::new(DataType::Null).len(array.len);
167 unsafe { builder.build_unchecked() }
168 }
169}
170
171impl std::fmt::Debug for NullArray {
172 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
173 write!(f, "NullArray({})", self.len())
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180 use crate::{Int64Array, StructArray, make_array};
181 use arrow_data::transform::MutableArrayData;
182 use arrow_schema::Field;
183
184 #[test]
185 fn test_null_array() {
186 let null_arr = NullArray::new(32);
187
188 assert_eq!(null_arr.len(), 32);
189 assert_eq!(null_arr.null_count(), 0);
190 assert_eq!(null_arr.logical_null_count(), 32);
191 assert_eq!(null_arr.logical_nulls().unwrap().null_count(), 32);
192 assert!(null_arr.is_valid(0));
193 assert!(null_arr.is_nullable());
194 }
195
196 #[test]
197 fn test_null_array_slice() {
198 let array1 = NullArray::new(32);
199
200 let array2 = array1.slice(8, 16);
201 assert_eq!(array2.len(), 16);
202 assert_eq!(array2.null_count(), 0);
203 assert_eq!(array2.logical_null_count(), 16);
204 assert_eq!(array2.logical_nulls().unwrap().null_count(), 16);
205 assert!(array2.is_valid(0));
206 assert!(array2.is_nullable());
207 }
208
209 #[test]
210 fn test_debug_null_array() {
211 let array = NullArray::new(1024 * 1024);
212 assert_eq!(format!("{array:?}"), "NullArray(1048576)");
213 }
214
215 #[test]
216 fn test_null_array_with_parent_null_buffer() {
217 let null_array = NullArray::new(1);
218 let int_array = Int64Array::from(vec![42]);
219
220 let fields = vec![
221 Field::new("a", DataType::Int64, true),
222 Field::new("b", DataType::Null, true),
223 ];
224
225 let struct_array_data = ArrayData::builder(DataType::Struct(fields.into()))
226 .len(1)
227 .add_child_data(int_array.to_data())
228 .add_child_data(null_array.to_data())
229 .build()
230 .unwrap();
231
232 let mut mutable = MutableArrayData::new(vec![&struct_array_data], true, 1);
233
234 mutable.try_extend_nulls(1).unwrap();
237 let data = mutable.freeze();
238
239 let struct_array = Arc::new(StructArray::from(data.clone()));
240 assert!(make_array(data) == struct_array);
241 }
242}