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