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