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 assert_eq!(
142 data.data_type(),
143 &DataType::Null,
144 "NullArray data type should be Null"
145 );
146 assert_eq!(
147 data.buffers().len(),
148 0,
149 "NullArray data should contain 0 buffers"
150 );
151 assert!(
152 data.nulls().is_none(),
153 "NullArray data should not contain a null buffer, as no buffers are required"
154 );
155 Self { len: data.len() }
156 }
157}
158
159impl From<NullArray> for ArrayData {
160 fn from(array: NullArray) -> Self {
161 let builder = ArrayDataBuilder::new(DataType::Null).len(array.len);
162 unsafe { builder.build_unchecked() }
163 }
164}
165
166impl std::fmt::Debug for NullArray {
167 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
168 write!(f, "NullArray({})", self.len())
169 }
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175 use crate::{Int64Array, StructArray, make_array};
176 use arrow_data::transform::MutableArrayData;
177 use arrow_schema::Field;
178
179 #[test]
180 fn test_null_array() {
181 let null_arr = NullArray::new(32);
182
183 assert_eq!(null_arr.len(), 32);
184 assert_eq!(null_arr.null_count(), 0);
185 assert_eq!(null_arr.logical_null_count(), 32);
186 assert_eq!(null_arr.logical_nulls().unwrap().null_count(), 32);
187 assert!(null_arr.is_valid(0));
188 assert!(null_arr.is_nullable());
189 }
190
191 #[test]
192 fn test_null_array_slice() {
193 let array1 = NullArray::new(32);
194
195 let array2 = array1.slice(8, 16);
196 assert_eq!(array2.len(), 16);
197 assert_eq!(array2.null_count(), 0);
198 assert_eq!(array2.logical_null_count(), 16);
199 assert_eq!(array2.logical_nulls().unwrap().null_count(), 16);
200 assert!(array2.is_valid(0));
201 assert!(array2.is_nullable());
202 }
203
204 #[test]
205 fn test_debug_null_array() {
206 let array = NullArray::new(1024 * 1024);
207 assert_eq!(format!("{array:?}"), "NullArray(1048576)");
208 }
209
210 #[test]
211 fn test_null_array_with_parent_null_buffer() {
212 let null_array = NullArray::new(1);
213 let int_array = Int64Array::from(vec![42]);
214
215 let fields = vec![
216 Field::new("a", DataType::Int64, true),
217 Field::new("b", DataType::Null, true),
218 ];
219
220 let struct_array_data = ArrayData::builder(DataType::Struct(fields.into()))
221 .len(1)
222 .add_child_data(int_array.to_data())
223 .add_child_data(null_array.to_data())
224 .build()
225 .unwrap();
226
227 let mut mutable = MutableArrayData::new(vec![&struct_array_data], true, 1);
228
229 mutable.extend_nulls(1);
232 let data = mutable.freeze();
233
234 let struct_array = Arc::new(StructArray::from(data.clone()));
235 assert!(make_array(data) == struct_array);
236 }
237}