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