1use std::sync::Arc;
5
6use arrow_array::AnyDictionaryArray;
7use arrow_array::Array as ArrowArray;
8use arrow_array::ArrowPrimitiveType;
9use arrow_array::BooleanArray as ArrowBooleanArray;
10use arrow_array::DictionaryArray;
11use arrow_array::FixedSizeListArray as ArrowFixedSizeListArray;
12use arrow_array::GenericByteArray;
13use arrow_array::GenericByteViewArray;
14use arrow_array::GenericListArray;
15use arrow_array::GenericListViewArray;
16use arrow_array::NullArray as ArrowNullArray;
17use arrow_array::OffsetSizeTrait;
18use arrow_array::PrimitiveArray as ArrowPrimitiveArray;
19use arrow_array::RecordBatch;
20use arrow_array::StructArray as ArrowStructArray;
21use arrow_array::cast::AsArray;
22use arrow_array::cast::as_null_array;
23use arrow_array::make_array;
24use arrow_array::types::ArrowDictionaryKeyType;
25use arrow_array::types::ByteArrayType;
26use arrow_array::types::ByteViewType;
27use arrow_array::types::Date32Type;
28use arrow_array::types::Date64Type;
29use arrow_array::types::Decimal32Type;
30use arrow_array::types::Decimal64Type;
31use arrow_array::types::Decimal128Type;
32use arrow_array::types::Decimal256Type;
33use arrow_array::types::Float16Type;
34use arrow_array::types::Float32Type;
35use arrow_array::types::Float64Type;
36use arrow_array::types::Int8Type;
37use arrow_array::types::Int16Type;
38use arrow_array::types::Int32Type;
39use arrow_array::types::Int64Type;
40use arrow_array::types::Time32MillisecondType;
41use arrow_array::types::Time32SecondType;
42use arrow_array::types::Time64MicrosecondType;
43use arrow_array::types::Time64NanosecondType;
44use arrow_array::types::TimestampMicrosecondType;
45use arrow_array::types::TimestampMillisecondType;
46use arrow_array::types::TimestampNanosecondType;
47use arrow_array::types::TimestampSecondType;
48use arrow_array::types::UInt8Type;
49use arrow_array::types::UInt16Type;
50use arrow_array::types::UInt32Type;
51use arrow_array::types::UInt64Type;
52use arrow_buffer::ArrowNativeType;
53use arrow_buffer::BooleanBuffer;
54use arrow_buffer::Buffer as ArrowBuffer;
55use arrow_buffer::ScalarBuffer;
56use arrow_buffer::buffer::NullBuffer;
57use arrow_buffer::buffer::OffsetBuffer;
58use arrow_schema::DataType;
59use arrow_schema::TimeUnit as ArrowTimeUnit;
60use itertools::Itertools;
61use vortex_buffer::Alignment;
62use vortex_buffer::BitBuffer;
63use vortex_buffer::Buffer;
64use vortex_buffer::ByteBuffer;
65use vortex_dtype::DType;
66use vortex_dtype::DecimalDType;
67use vortex_dtype::IntegerPType;
68use vortex_dtype::NativePType;
69use vortex_dtype::PType;
70use vortex_dtype::datetime::TimeUnit;
71use vortex_error::VortexExpect as _;
72use vortex_error::vortex_panic;
73use vortex_scalar::i256;
74
75use crate::ArrayRef;
76use crate::IntoArray;
77use crate::arrays::BoolArray;
78use crate::arrays::DecimalArray;
79use crate::arrays::DictArray;
80use crate::arrays::FixedSizeListArray;
81use crate::arrays::ListArray;
82use crate::arrays::ListViewArray;
83use crate::arrays::NullArray;
84use crate::arrays::PrimitiveArray;
85use crate::arrays::StructArray;
86use crate::arrays::TemporalArray;
87use crate::arrays::VarBinArray;
88use crate::arrays::VarBinViewArray;
89use crate::arrow::FromArrowArray;
90use crate::validity::Validity;
91
92impl IntoArray for ArrowBuffer {
93 fn into_array(self) -> ArrayRef {
94 PrimitiveArray::from_byte_buffer(
95 ByteBuffer::from_arrow_buffer(self, Alignment::of::<u8>()),
96 PType::U8,
97 Validity::NonNullable,
98 )
99 .into_array()
100 }
101}
102
103impl IntoArray for BooleanBuffer {
104 fn into_array(self) -> ArrayRef {
105 BoolArray::from_bit_buffer(self.into(), Validity::NonNullable).into_array()
106 }
107}
108
109impl<T> IntoArray for ScalarBuffer<T>
110where
111 T: ArrowNativeType + NativePType,
112{
113 fn into_array(self) -> ArrayRef {
114 PrimitiveArray::new(
115 Buffer::<T>::from_arrow_scalar_buffer(self),
116 Validity::NonNullable,
117 )
118 .into_array()
119 }
120}
121
122impl<O> IntoArray for OffsetBuffer<O>
123where
124 O: IntegerPType + OffsetSizeTrait,
125{
126 fn into_array(self) -> ArrayRef {
127 let primitive = PrimitiveArray::new(
128 Buffer::from_arrow_scalar_buffer(self.into_inner()),
129 Validity::NonNullable,
130 );
131
132 primitive.into_array()
133 }
134}
135
136macro_rules! impl_from_arrow_primitive {
137 ($T:path) => {
138 impl FromArrowArray<&ArrowPrimitiveArray<$T>> for ArrayRef {
139 fn from_arrow(value: &ArrowPrimitiveArray<$T>, nullable: bool) -> Self {
140 let buffer = Buffer::from_arrow_scalar_buffer(value.values().clone());
141 let validity = nulls(value.nulls(), nullable);
142 PrimitiveArray::new(buffer, validity).into_array()
143 }
144 }
145 };
146}
147
148impl_from_arrow_primitive!(Int8Type);
149impl_from_arrow_primitive!(Int16Type);
150impl_from_arrow_primitive!(Int32Type);
151impl_from_arrow_primitive!(Int64Type);
152impl_from_arrow_primitive!(UInt8Type);
153impl_from_arrow_primitive!(UInt16Type);
154impl_from_arrow_primitive!(UInt32Type);
155impl_from_arrow_primitive!(UInt64Type);
156impl_from_arrow_primitive!(Float16Type);
157impl_from_arrow_primitive!(Float32Type);
158impl_from_arrow_primitive!(Float64Type);
159
160impl FromArrowArray<&ArrowPrimitiveArray<Decimal32Type>> for ArrayRef {
161 fn from_arrow(array: &ArrowPrimitiveArray<Decimal32Type>, nullable: bool) -> Self {
162 let decimal_type = DecimalDType::new(array.precision(), array.scale());
163 let buffer = Buffer::from_arrow_scalar_buffer(array.values().clone());
164 let validity = nulls(array.nulls(), nullable);
165 DecimalArray::new(buffer, decimal_type, validity).into_array()
166 }
167}
168
169impl FromArrowArray<&ArrowPrimitiveArray<Decimal64Type>> for ArrayRef {
170 fn from_arrow(array: &ArrowPrimitiveArray<Decimal64Type>, nullable: bool) -> Self {
171 let decimal_type = DecimalDType::new(array.precision(), array.scale());
172 let buffer = Buffer::from_arrow_scalar_buffer(array.values().clone());
173 let validity = nulls(array.nulls(), nullable);
174 DecimalArray::new(buffer, decimal_type, validity).into_array()
175 }
176}
177
178impl FromArrowArray<&ArrowPrimitiveArray<Decimal128Type>> for ArrayRef {
179 fn from_arrow(array: &ArrowPrimitiveArray<Decimal128Type>, nullable: bool) -> Self {
180 let decimal_type = DecimalDType::new(array.precision(), array.scale());
181 let buffer = Buffer::from_arrow_scalar_buffer(array.values().clone());
182 let validity = nulls(array.nulls(), nullable);
183 DecimalArray::new(buffer, decimal_type, validity).into_array()
184 }
185}
186
187impl FromArrowArray<&ArrowPrimitiveArray<Decimal256Type>> for ArrayRef {
188 fn from_arrow(array: &ArrowPrimitiveArray<Decimal256Type>, nullable: bool) -> Self {
189 let decimal_type = DecimalDType::new(array.precision(), array.scale());
190 let buffer = Buffer::from_arrow_scalar_buffer(array.values().clone());
191 let buffer =
195 unsafe { std::mem::transmute::<Buffer<arrow_buffer::i256>, Buffer<i256>>(buffer) };
196 let validity = nulls(array.nulls(), nullable);
197 DecimalArray::new(buffer, decimal_type, validity).into_array()
198 }
199}
200
201macro_rules! impl_from_arrow_temporal {
202 ($T:path) => {
203 impl FromArrowArray<&ArrowPrimitiveArray<$T>> for ArrayRef {
204 fn from_arrow(value: &ArrowPrimitiveArray<$T>, nullable: bool) -> Self {
205 temporal_array(value, nullable)
206 }
207 }
208 };
209}
210
211impl_from_arrow_temporal!(TimestampSecondType);
213impl_from_arrow_temporal!(TimestampMillisecondType);
214impl_from_arrow_temporal!(TimestampMicrosecondType);
215impl_from_arrow_temporal!(TimestampNanosecondType);
216
217impl_from_arrow_temporal!(Time32SecondType);
219impl_from_arrow_temporal!(Time32MillisecondType);
220impl_from_arrow_temporal!(Time64MicrosecondType);
221impl_from_arrow_temporal!(Time64NanosecondType);
222
223impl_from_arrow_temporal!(Date32Type);
225impl_from_arrow_temporal!(Date64Type);
226
227fn temporal_array<T: ArrowPrimitiveType>(value: &ArrowPrimitiveArray<T>, nullable: bool) -> ArrayRef
228where
229 T::Native: NativePType,
230{
231 let arr = PrimitiveArray::new(
232 Buffer::from_arrow_scalar_buffer(value.values().clone()),
233 nulls(value.nulls(), nullable),
234 )
235 .into_array();
236
237 match value.data_type() {
238 DataType::Timestamp(time_unit, tz) => {
239 let tz = tz.as_ref().map(|s| s.to_string());
240 TemporalArray::new_timestamp(arr, time_unit.into(), tz).into()
241 }
242 DataType::Time32(time_unit) => TemporalArray::new_time(arr, time_unit.into()).into(),
243 DataType::Time64(time_unit) => TemporalArray::new_time(arr, time_unit.into()).into(),
244 DataType::Date32 => TemporalArray::new_date(arr, TimeUnit::Days).into(),
245 DataType::Date64 => TemporalArray::new_date(arr, TimeUnit::Milliseconds).into(),
246 DataType::Duration(_) => unimplemented!(),
247 DataType::Interval(_) => unimplemented!(),
248 _ => vortex_panic!("Invalid temporal type: {}", value.data_type()),
249 }
250}
251
252impl<T: ByteArrayType> FromArrowArray<&GenericByteArray<T>> for ArrayRef
253where
254 <T as ByteArrayType>::Offset: IntegerPType,
255{
256 fn from_arrow(value: &GenericByteArray<T>, nullable: bool) -> Self {
257 let dtype = match T::DATA_TYPE {
258 DataType::Binary | DataType::LargeBinary => DType::Binary(nullable.into()),
259 DataType::Utf8 | DataType::LargeUtf8 => DType::Utf8(nullable.into()),
260 dt => vortex_panic!("Invalid data type for ByteArray: {dt}"),
261 };
262 VarBinArray::try_new(
263 value.offsets().clone().into_array(),
264 ByteBuffer::from_arrow_buffer(value.values().clone(), Alignment::of::<u8>()),
265 dtype,
266 nulls(value.nulls(), nullable),
267 )
268 .vortex_expect("Failed to convert Arrow GenericByteArray to Vortex VarBinArray")
269 .into_array()
270 }
271}
272
273impl<T: ByteViewType> FromArrowArray<&GenericByteViewArray<T>> for ArrayRef {
274 fn from_arrow(value: &GenericByteViewArray<T>, nullable: bool) -> Self {
275 let dtype = match T::DATA_TYPE {
276 DataType::BinaryView => DType::Binary(nullable.into()),
277 DataType::Utf8View => DType::Utf8(nullable.into()),
278 dt => vortex_panic!("Invalid data type for ByteViewArray: {dt}"),
279 };
280
281 let views_buffer = Buffer::from_byte_buffer(
282 Buffer::from_arrow_scalar_buffer(value.views().clone()).into_byte_buffer(),
283 );
284
285 unsafe {
288 VarBinViewArray::new_unchecked(
289 views_buffer,
290 Arc::from(
291 value
292 .data_buffers()
293 .iter()
294 .map(|b| ByteBuffer::from_arrow_buffer(b.clone(), Alignment::of::<u8>()))
295 .collect::<Vec<_>>(),
296 ),
297 dtype,
298 nulls(value.nulls(), nullable),
299 )
300 .into_array()
301 }
302 }
303}
304
305impl FromArrowArray<&ArrowBooleanArray> for ArrayRef {
306 fn from_arrow(value: &ArrowBooleanArray, nullable: bool) -> Self {
307 BoolArray::from_bit_buffer(
308 value.values().clone().into(),
309 nulls(value.nulls(), nullable),
310 )
311 .into_array()
312 }
313}
314
315fn remove_nulls(data: arrow_data::ArrayData) -> arrow_data::ArrayData {
317 if data.null_count() == 0 {
318 return data;
320 }
321
322 let children = match data.data_type() {
323 DataType::Struct(fields) => Some(
324 fields
325 .iter()
326 .zip(data.child_data().iter())
327 .map(|(field, child_data)| {
328 if field.is_nullable() {
329 child_data.clone()
330 } else {
331 remove_nulls(child_data.clone())
332 }
333 })
334 .collect_vec(),
335 ),
336 DataType::List(f)
337 | DataType::LargeList(f)
338 | DataType::ListView(f)
339 | DataType::LargeListView(f)
340 | DataType::FixedSizeList(f, _)
341 if !f.is_nullable() =>
342 {
343 assert_eq!(
345 data.child_data().len(),
346 1,
347 "List types should have one child"
348 );
349 Some(vec![remove_nulls(data.child_data()[0].clone())])
350 }
351 _ => None,
352 };
353
354 let mut builder = data.into_builder().nulls(None);
355 if let Some(children) = children {
356 builder = builder.child_data(children);
357 }
358 builder
359 .build()
360 .vortex_expect("reconstructing array without nulls")
361}
362
363impl FromArrowArray<&ArrowStructArray> for ArrayRef {
364 fn from_arrow(value: &ArrowStructArray, nullable: bool) -> Self {
365 StructArray::try_new(
366 value.column_names().iter().copied().collect(),
367 value
368 .columns()
369 .iter()
370 .zip(value.fields())
371 .map(|(c, field)| {
372 if c.null_count() > 0 && !field.is_nullable() {
375 let stripped = make_array(remove_nulls(c.into_data()));
376 Self::from_arrow(stripped.as_ref(), false)
377 } else {
378 Self::from_arrow(c.as_ref(), field.is_nullable())
379 }
380 })
381 .collect::<Vec<_>>(),
382 value.len(),
383 nulls(value.nulls(), nullable),
384 )
385 .vortex_expect("Failed to convert Arrow StructArray to Vortex StructArray")
386 .into_array()
387 }
388}
389
390impl<O: IntegerPType + OffsetSizeTrait> FromArrowArray<&GenericListArray<O>> for ArrayRef {
391 fn from_arrow(value: &GenericListArray<O>, nullable: bool) -> Self {
392 let elements_are_nullable = match value.data_type() {
394 DataType::List(field) => field.is_nullable(),
395 DataType::LargeList(field) => field.is_nullable(),
396 dt => vortex_panic!("Invalid data type for ListArray: {dt}"),
397 };
398
399 let elements = Self::from_arrow(value.values().as_ref(), elements_are_nullable);
400
401 let offsets = value.offsets().clone().into_array();
403 let nulls = nulls(value.nulls(), nullable);
404
405 ListArray::try_new(elements, offsets, nulls)
406 .vortex_expect("Failed to convert Arrow ListArray to Vortex ListArray")
407 .into_array()
408 }
409}
410
411impl<O: OffsetSizeTrait + NativePType> FromArrowArray<&GenericListViewArray<O>> for ArrayRef {
412 fn from_arrow(array: &GenericListViewArray<O>, nullable: bool) -> Self {
413 let elements_are_nullable = match array.data_type() {
415 DataType::ListView(field) => field.is_nullable(),
416 DataType::LargeListView(field) => field.is_nullable(),
417 dt => vortex_panic!("Invalid data type for ListViewArray: {dt}"),
418 };
419
420 let elements = Self::from_arrow(array.values().as_ref(), elements_are_nullable);
421
422 let offsets = array.offsets().clone().into_array();
424 let sizes = array.sizes().clone().into_array();
425 let nulls = nulls(array.nulls(), nullable);
426
427 ListViewArray::try_new(elements, offsets, sizes, nulls)
428 .vortex_expect("Failed to convert Arrow ListViewArray to Vortex ListViewArray")
429 .into_array()
430 }
431}
432
433impl FromArrowArray<&ArrowFixedSizeListArray> for ArrayRef {
434 fn from_arrow(array: &ArrowFixedSizeListArray, nullable: bool) -> Self {
435 let DataType::FixedSizeList(field, list_size) = array.data_type() else {
436 vortex_panic!("Invalid data type for ListArray: {}", array.data_type());
437 };
438
439 FixedSizeListArray::try_new(
440 Self::from_arrow(array.values().as_ref(), field.is_nullable()),
441 *list_size as u32,
442 nulls(array.nulls(), nullable),
443 array.len(),
444 )
445 .vortex_expect("Failed to convert Arrow FixedSizeListArray to Vortex FixedSizeListArray")
446 .into_array()
447 }
448}
449
450impl FromArrowArray<&ArrowNullArray> for ArrayRef {
451 fn from_arrow(value: &ArrowNullArray, nullable: bool) -> Self {
452 assert!(nullable);
453 NullArray::new(value.len()).into_array()
454 }
455}
456
457impl<K: ArrowDictionaryKeyType> FromArrowArray<&DictionaryArray<K>> for DictArray {
458 fn from_arrow(array: &DictionaryArray<K>, nullable: bool) -> Self {
459 let keys = AnyDictionaryArray::keys(array);
460 let keys = ArrayRef::from_arrow(keys, keys.is_nullable());
461 let values = ArrayRef::from_arrow(array.values().as_ref(), nullable);
462 unsafe { DictArray::new_unchecked(keys, values) }
464 }
465}
466
467fn nulls(nulls: Option<&NullBuffer>, nullable: bool) -> Validity {
468 if nullable {
469 nulls
470 .map(|nulls| {
471 if nulls.null_count() == nulls.len() {
472 Validity::AllInvalid
473 } else {
474 Validity::from(BitBuffer::from(nulls.inner().clone()))
475 }
476 })
477 .unwrap_or_else(|| Validity::AllValid)
478 } else {
479 assert!(nulls.map(|x| x.null_count() == 0).unwrap_or(true));
480 Validity::NonNullable
481 }
482}
483
484impl FromArrowArray<&dyn ArrowArray> for ArrayRef {
485 fn from_arrow(array: &dyn ArrowArray, nullable: bool) -> Self {
486 match array.data_type() {
487 DataType::Boolean => Self::from_arrow(array.as_boolean(), nullable),
488 DataType::UInt8 => Self::from_arrow(array.as_primitive::<UInt8Type>(), nullable),
489 DataType::UInt16 => Self::from_arrow(array.as_primitive::<UInt16Type>(), nullable),
490 DataType::UInt32 => Self::from_arrow(array.as_primitive::<UInt32Type>(), nullable),
491 DataType::UInt64 => Self::from_arrow(array.as_primitive::<UInt64Type>(), nullable),
492 DataType::Int8 => Self::from_arrow(array.as_primitive::<Int8Type>(), nullable),
493 DataType::Int16 => Self::from_arrow(array.as_primitive::<Int16Type>(), nullable),
494 DataType::Int32 => Self::from_arrow(array.as_primitive::<Int32Type>(), nullable),
495 DataType::Int64 => Self::from_arrow(array.as_primitive::<Int64Type>(), nullable),
496 DataType::Float16 => Self::from_arrow(array.as_primitive::<Float16Type>(), nullable),
497 DataType::Float32 => Self::from_arrow(array.as_primitive::<Float32Type>(), nullable),
498 DataType::Float64 => Self::from_arrow(array.as_primitive::<Float64Type>(), nullable),
499 DataType::Utf8 => Self::from_arrow(array.as_string::<i32>(), nullable),
500 DataType::LargeUtf8 => Self::from_arrow(array.as_string::<i64>(), nullable),
501 DataType::Binary => Self::from_arrow(array.as_binary::<i32>(), nullable),
502 DataType::LargeBinary => Self::from_arrow(array.as_binary::<i64>(), nullable),
503 DataType::BinaryView => Self::from_arrow(array.as_binary_view(), nullable),
504 DataType::Utf8View => Self::from_arrow(array.as_string_view(), nullable),
505 DataType::Struct(_) => Self::from_arrow(array.as_struct(), nullable),
506 DataType::List(_) => Self::from_arrow(array.as_list::<i32>(), nullable),
507 DataType::LargeList(_) => Self::from_arrow(array.as_list::<i64>(), nullable),
508 DataType::ListView(_) => Self::from_arrow(array.as_list_view::<i32>(), nullable),
509 DataType::LargeListView(_) => Self::from_arrow(array.as_list_view::<i64>(), nullable),
510 DataType::FixedSizeList(..) => Self::from_arrow(array.as_fixed_size_list(), nullable),
511 DataType::Null => Self::from_arrow(as_null_array(array), nullable),
512 DataType::Timestamp(u, _) => match u {
513 ArrowTimeUnit::Second => {
514 Self::from_arrow(array.as_primitive::<TimestampSecondType>(), nullable)
515 }
516 ArrowTimeUnit::Millisecond => {
517 Self::from_arrow(array.as_primitive::<TimestampMillisecondType>(), nullable)
518 }
519 ArrowTimeUnit::Microsecond => {
520 Self::from_arrow(array.as_primitive::<TimestampMicrosecondType>(), nullable)
521 }
522 ArrowTimeUnit::Nanosecond => {
523 Self::from_arrow(array.as_primitive::<TimestampNanosecondType>(), nullable)
524 }
525 },
526 DataType::Date32 => Self::from_arrow(array.as_primitive::<Date32Type>(), nullable),
527 DataType::Date64 => Self::from_arrow(array.as_primitive::<Date64Type>(), nullable),
528 DataType::Time32(u) => match u {
529 ArrowTimeUnit::Second => {
530 Self::from_arrow(array.as_primitive::<Time32SecondType>(), nullable)
531 }
532 ArrowTimeUnit::Millisecond => {
533 Self::from_arrow(array.as_primitive::<Time32MillisecondType>(), nullable)
534 }
535 ArrowTimeUnit::Microsecond | ArrowTimeUnit::Nanosecond => unreachable!(),
536 },
537 DataType::Time64(u) => match u {
538 ArrowTimeUnit::Microsecond => {
539 Self::from_arrow(array.as_primitive::<Time64MicrosecondType>(), nullable)
540 }
541 ArrowTimeUnit::Nanosecond => {
542 Self::from_arrow(array.as_primitive::<Time64NanosecondType>(), nullable)
543 }
544 ArrowTimeUnit::Second | ArrowTimeUnit::Millisecond => unreachable!(),
545 },
546 DataType::Decimal32(..) => {
547 Self::from_arrow(array.as_primitive::<Decimal32Type>(), nullable)
548 }
549 DataType::Decimal64(..) => {
550 Self::from_arrow(array.as_primitive::<Decimal64Type>(), nullable)
551 }
552 DataType::Decimal128(..) => {
553 Self::from_arrow(array.as_primitive::<Decimal128Type>(), nullable)
554 }
555 DataType::Decimal256(..) => {
556 Self::from_arrow(array.as_primitive::<Decimal256Type>(), nullable)
557 }
558 DataType::Dictionary(key_type, _) => match key_type.as_ref() {
559 DataType::Int8 => {
560 DictArray::from_arrow(array.as_dictionary::<Int8Type>(), nullable).into_array()
561 }
562 DataType::Int16 => {
563 DictArray::from_arrow(array.as_dictionary::<Int16Type>(), nullable).into_array()
564 }
565 DataType::Int32 => {
566 DictArray::from_arrow(array.as_dictionary::<Int32Type>(), nullable).into_array()
567 }
568 DataType::Int64 => {
569 DictArray::from_arrow(array.as_dictionary::<Int64Type>(), nullable).into_array()
570 }
571 DataType::UInt8 => {
572 DictArray::from_arrow(array.as_dictionary::<UInt8Type>(), nullable).into_array()
573 }
574 DataType::UInt16 => {
575 DictArray::from_arrow(array.as_dictionary::<UInt16Type>(), nullable)
576 .into_array()
577 }
578 DataType::UInt32 => {
579 DictArray::from_arrow(array.as_dictionary::<UInt32Type>(), nullable)
580 .into_array()
581 }
582 DataType::UInt64 => {
583 DictArray::from_arrow(array.as_dictionary::<UInt64Type>(), nullable)
584 .into_array()
585 }
586 key_dt => vortex_panic!("Unsupported dictionary key type: {key_dt}"),
587 },
588 dt => vortex_panic!("Array encoding not implemented for Arrow data type {dt}"),
589 }
590 }
591}
592
593impl FromArrowArray<RecordBatch> for ArrayRef {
594 fn from_arrow(array: RecordBatch, nullable: bool) -> Self {
595 ArrayRef::from_arrow(&arrow_array::StructArray::from(array), nullable)
596 }
597}
598
599impl FromArrowArray<&RecordBatch> for ArrayRef {
600 fn from_arrow(array: &RecordBatch, nullable: bool) -> Self {
601 Self::from_arrow(array.clone(), nullable)
602 }
603}
604
605#[cfg(test)]
606mod tests {
607 use std::sync::Arc;
608
609 use arrow_array::Array as ArrowArray;
610 use arrow_array::BinaryArray;
611 use arrow_array::BooleanArray;
612 use arrow_array::Date32Array;
613 use arrow_array::Date64Array;
614 use arrow_array::FixedSizeListArray as ArrowFixedSizeListArray;
615 use arrow_array::Float32Array;
616 use arrow_array::Float64Array;
617 use arrow_array::GenericListViewArray;
618 use arrow_array::Int8Array;
619 use arrow_array::Int16Array;
620 use arrow_array::Int32Array;
621 use arrow_array::Int64Array;
622 use arrow_array::LargeBinaryArray;
623 use arrow_array::LargeStringArray;
624 use arrow_array::NullArray;
625 use arrow_array::RecordBatch;
626 use arrow_array::StringArray;
627 use arrow_array::StructArray;
628 use arrow_array::Time32MillisecondArray;
629 use arrow_array::Time32SecondArray;
630 use arrow_array::Time64MicrosecondArray;
631 use arrow_array::Time64NanosecondArray;
632 use arrow_array::TimestampMicrosecondArray;
633 use arrow_array::TimestampMillisecondArray;
634 use arrow_array::TimestampNanosecondArray;
635 use arrow_array::TimestampSecondArray;
636 use arrow_array::UInt8Array;
637 use arrow_array::UInt16Array;
638 use arrow_array::UInt32Array;
639 use arrow_array::UInt64Array;
640 use arrow_array::builder::BinaryViewBuilder;
641 use arrow_array::builder::Decimal128Builder;
642 use arrow_array::builder::Decimal256Builder;
643 use arrow_array::builder::Int32Builder;
644 use arrow_array::builder::LargeListBuilder;
645 use arrow_array::builder::ListBuilder;
646 use arrow_array::builder::StringViewBuilder;
647 use arrow_array::new_null_array;
648 use arrow_array::types::ArrowPrimitiveType;
649 use arrow_array::types::Float16Type;
650 use arrow_buffer::BooleanBuffer;
651 use arrow_buffer::Buffer as ArrowBuffer;
652 use arrow_buffer::OffsetBuffer;
653 use arrow_buffer::ScalarBuffer;
654 use arrow_schema::DataType;
655 use arrow_schema::Field;
656 use arrow_schema::Fields;
657 use arrow_schema::Schema;
658 use vortex_dtype::DType;
659 use vortex_dtype::ExtDType;
660 use vortex_dtype::Nullability;
661 use vortex_dtype::PType;
662 use vortex_dtype::datetime::TIMESTAMP_ID;
663 use vortex_dtype::datetime::TemporalMetadata;
664 use vortex_dtype::datetime::TimeUnit;
665
666 use crate::ArrayRef;
667 use crate::IntoArray;
668 use crate::arrays::DecimalVTable;
669 use crate::arrays::FixedSizeListVTable;
670 use crate::arrays::ListVTable;
671 use crate::arrays::ListViewVTable;
672 use crate::arrays::PrimitiveVTable;
673 use crate::arrays::StructVTable;
674 use crate::arrays::TemporalArray;
675 use crate::arrays::VarBinVTable;
676 use crate::arrays::VarBinViewVTable;
677 use crate::arrow::FromArrowArray as _;
678
679 #[test]
681 fn test_int8_array_conversion() {
682 let arrow_array = Int8Array::from(vec![Some(1), None, Some(3), Some(4)]);
683 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
684
685 let arrow_array_non_null = Int8Array::from(vec![1, 2, 3, 4]);
686 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
687
688 assert_eq!(vortex_array.len(), 4);
689 assert_eq!(vortex_array_non_null.len(), 4);
690
691 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
693 assert_eq!(primitive_array.ptype(), PType::I8);
694
695 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
696 assert_eq!(primitive_array_non_null.ptype(), PType::I8);
697 }
698
699 #[test]
700 fn test_int16_array_conversion() {
701 let arrow_array = Int16Array::from(vec![Some(100), None, Some(300), Some(400)]);
702 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
703
704 let arrow_array_non_null = Int16Array::from(vec![100, 200, 300, 400]);
705 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
706
707 assert_eq!(vortex_array.len(), 4);
708 assert_eq!(vortex_array_non_null.len(), 4);
709
710 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
712 assert_eq!(primitive_array.ptype(), PType::I16);
713
714 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
715 assert_eq!(primitive_array_non_null.ptype(), PType::I16);
716 }
717
718 #[test]
719 fn test_int32_array_conversion() {
720 let arrow_array = Int32Array::from(vec![Some(1000), None, Some(3000), Some(4000)]);
721 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
722
723 let arrow_array_non_null = Int32Array::from(vec![1000, 2000, 3000, 4000]);
724 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
725
726 assert_eq!(vortex_array.len(), 4);
727 assert_eq!(vortex_array_non_null.len(), 4);
728
729 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
731 assert_eq!(primitive_array.ptype(), PType::I32);
732
733 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
734 assert_eq!(primitive_array_non_null.ptype(), PType::I32);
735 }
736
737 #[test]
738 fn test_int64_array_conversion() {
739 let arrow_array = Int64Array::from(vec![Some(10000), None, Some(30000), Some(40000)]);
740 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
741
742 let arrow_array_non_null = Int64Array::from(vec![10000_i64, 20000, 30000, 40000]);
743 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
744
745 assert_eq!(vortex_array.len(), 4);
746 assert_eq!(vortex_array_non_null.len(), 4);
747
748 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
750 assert_eq!(primitive_array.ptype(), PType::I64);
751
752 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
753 assert_eq!(primitive_array_non_null.ptype(), PType::I64);
754 }
755
756 #[test]
757 fn test_uint8_array_conversion() {
758 let arrow_array = UInt8Array::from(vec![Some(1), None, Some(3), Some(4)]);
759 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
760
761 let arrow_array_non_null = UInt8Array::from(vec![1_u8, 2, 3, 4]);
762 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
763
764 assert_eq!(vortex_array.len(), 4);
765 assert_eq!(vortex_array_non_null.len(), 4);
766
767 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
769 assert_eq!(primitive_array.ptype(), PType::U8);
770
771 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
772 assert_eq!(primitive_array_non_null.ptype(), PType::U8);
773 }
774
775 #[test]
776 fn test_uint16_array_conversion() {
777 let arrow_array = UInt16Array::from(vec![Some(100), None, Some(300), Some(400)]);
778 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
779
780 let arrow_array_non_null = UInt16Array::from(vec![100_u16, 200, 300, 400]);
781 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
782
783 assert_eq!(vortex_array.len(), 4);
784 assert_eq!(vortex_array_non_null.len(), 4);
785
786 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
788 assert_eq!(primitive_array.ptype(), PType::U16);
789
790 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
791 assert_eq!(primitive_array_non_null.ptype(), PType::U16);
792 }
793
794 #[test]
795 fn test_uint32_array_conversion() {
796 let arrow_array = UInt32Array::from(vec![Some(1000), None, Some(3000), Some(4000)]);
797 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
798
799 let arrow_array_non_null = UInt32Array::from(vec![1000_u32, 2000, 3000, 4000]);
800 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
801
802 assert_eq!(vortex_array.len(), 4);
803 assert_eq!(vortex_array_non_null.len(), 4);
804
805 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
807 assert_eq!(primitive_array.ptype(), PType::U32);
808
809 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
810 assert_eq!(primitive_array_non_null.ptype(), PType::U32);
811 }
812
813 #[test]
814 fn test_uint64_array_conversion() {
815 let arrow_array = UInt64Array::from(vec![Some(10000), None, Some(30000), Some(40000)]);
816 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
817
818 let arrow_array_non_null = UInt64Array::from(vec![10000_u64, 20000, 30000, 40000]);
819 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
820
821 assert_eq!(vortex_array.len(), 4);
822 assert_eq!(vortex_array_non_null.len(), 4);
823
824 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
826 assert_eq!(primitive_array.ptype(), PType::U64);
827
828 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
829 assert_eq!(primitive_array_non_null.ptype(), PType::U64);
830 }
831
832 #[test]
833 fn test_float16_array_conversion() {
834 let values = vec![
835 Some(<Float16Type as ArrowPrimitiveType>::Native::from_f32(1.5)),
836 None,
837 Some(<Float16Type as ArrowPrimitiveType>::Native::from_f32(3.5)),
838 ];
839 let arrow_array = arrow_array::PrimitiveArray::<Float16Type>::from(values);
840 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
841
842 let non_null_values = vec![
843 <Float16Type as ArrowPrimitiveType>::Native::from_f32(1.5),
844 <Float16Type as ArrowPrimitiveType>::Native::from_f32(2.5),
845 ];
846 let arrow_array_non_null =
847 arrow_array::PrimitiveArray::<Float16Type>::from(non_null_values);
848 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
849
850 assert_eq!(vortex_array.len(), 3);
851 assert_eq!(vortex_array_non_null.len(), 2);
852
853 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
855 assert_eq!(primitive_array.ptype(), PType::F16);
856
857 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
858 assert_eq!(primitive_array_non_null.ptype(), PType::F16);
859 }
860
861 #[test]
862 fn test_float32_array_conversion() {
863 let arrow_array = Float32Array::from(vec![Some(1.5), None, Some(3.5), Some(4.5)]);
864 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
865
866 let arrow_array_non_null = Float32Array::from(vec![1.5_f32, 2.5, 3.5, 4.5]);
867 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
868
869 assert_eq!(vortex_array.len(), 4);
870 assert_eq!(vortex_array_non_null.len(), 4);
871
872 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
874 assert_eq!(primitive_array.ptype(), PType::F32);
875
876 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
877 assert_eq!(primitive_array_non_null.ptype(), PType::F32);
878 }
879
880 #[test]
881 fn test_float64_array_conversion() {
882 let arrow_array = Float64Array::from(vec![Some(1.5), None, Some(3.5), Some(4.5)]);
883 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
884
885 let arrow_array_non_null = Float64Array::from(vec![1.5_f64, 2.5, 3.5, 4.5]);
886 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
887
888 assert_eq!(vortex_array.len(), 4);
889 assert_eq!(vortex_array_non_null.len(), 4);
890
891 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
893 assert_eq!(primitive_array.ptype(), PType::F64);
894
895 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
896 assert_eq!(primitive_array_non_null.ptype(), PType::F64);
897 }
898
899 #[test]
901 fn test_decimal128_array_conversion() {
902 let mut builder = Decimal128Builder::with_capacity(4);
903 builder.append_value(12345);
904 builder.append_null();
905 builder.append_value(67890);
906 builder.append_value(11111);
907 let decimal_array = builder.finish().with_precision_and_scale(10, 2).unwrap();
908
909 let vortex_array = ArrayRef::from_arrow(&decimal_array, true);
910 assert_eq!(vortex_array.len(), 4);
911
912 let mut builder_non_null = Decimal128Builder::with_capacity(3);
913 builder_non_null.append_value(12345);
914 builder_non_null.append_value(67890);
915 builder_non_null.append_value(11111);
916 let decimal_array_non_null = builder_non_null
917 .finish()
918 .with_precision_and_scale(10, 2)
919 .unwrap();
920
921 let vortex_array_non_null = ArrayRef::from_arrow(&decimal_array_non_null, false);
922 assert_eq!(vortex_array_non_null.len(), 3);
923
924 let decimal_vortex_array = vortex_array.as_::<DecimalVTable>();
926 assert_eq!(decimal_vortex_array.decimal_dtype().precision(), 10);
927 assert_eq!(decimal_vortex_array.decimal_dtype().scale(), 2);
928
929 let decimal_vortex_array_non_null = vortex_array_non_null.as_::<DecimalVTable>();
930 assert_eq!(
931 decimal_vortex_array_non_null.decimal_dtype().precision(),
932 10
933 );
934 assert_eq!(decimal_vortex_array_non_null.decimal_dtype().scale(), 2);
935 }
936
937 #[test]
938 fn test_decimal256_array_conversion() {
939 let mut builder = Decimal256Builder::with_capacity(4);
940 builder.append_value(arrow_buffer::i256::from_i128(12345));
941 builder.append_null();
942 builder.append_value(arrow_buffer::i256::from_i128(67890));
943 builder.append_value(arrow_buffer::i256::from_i128(11111));
944 let decimal_array = builder.finish().with_precision_and_scale(38, 10).unwrap();
945
946 let vortex_array = ArrayRef::from_arrow(&decimal_array, true);
947 assert_eq!(vortex_array.len(), 4);
948
949 let mut builder_non_null = Decimal256Builder::with_capacity(3);
950 builder_non_null.append_value(arrow_buffer::i256::from_i128(12345));
951 builder_non_null.append_value(arrow_buffer::i256::from_i128(67890));
952 builder_non_null.append_value(arrow_buffer::i256::from_i128(11111));
953 let decimal_array_non_null = builder_non_null
954 .finish()
955 .with_precision_and_scale(38, 10)
956 .unwrap();
957
958 let vortex_array_non_null = ArrayRef::from_arrow(&decimal_array_non_null, false);
959 assert_eq!(vortex_array_non_null.len(), 3);
960
961 let decimal_vortex_array = vortex_array.as_::<DecimalVTable>();
963 assert_eq!(decimal_vortex_array.decimal_dtype().precision(), 38);
964 assert_eq!(decimal_vortex_array.decimal_dtype().scale(), 10);
965
966 let decimal_vortex_array_non_null = vortex_array_non_null.as_::<DecimalVTable>();
967 assert_eq!(
968 decimal_vortex_array_non_null.decimal_dtype().precision(),
969 38
970 );
971 assert_eq!(decimal_vortex_array_non_null.decimal_dtype().scale(), 10);
972 }
973
974 #[test]
976 fn test_timestamp_second_array_conversion() {
977 let arrow_array =
978 TimestampSecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
979 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
980
981 let arrow_array_non_null = TimestampSecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
982 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
983
984 assert_eq!(vortex_array.len(), 4);
985 assert_eq!(vortex_array_non_null.len(), 4);
986
987 let temporal_array = TemporalArray::try_from(vortex_array.clone()).unwrap();
989 assert_eq!(
990 temporal_array.temporal_metadata().time_unit(),
991 TimeUnit::Seconds
992 );
993
994 let temporal_array_non_null =
995 TemporalArray::try_from(vortex_array_non_null.clone()).unwrap();
996 assert_eq!(
997 temporal_array_non_null.temporal_metadata().time_unit(),
998 TimeUnit::Seconds
999 );
1000 }
1001
1002 #[test]
1003 fn test_timestamp_millisecond_array_conversion() {
1004 let arrow_array =
1005 TimestampMillisecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
1006 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1007
1008 let arrow_array_non_null =
1009 TimestampMillisecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
1010 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1011
1012 assert_eq!(vortex_array.len(), 4);
1013 assert_eq!(vortex_array_non_null.len(), 4);
1014 }
1015
1016 #[test]
1017 fn test_timestamp_microsecond_array_conversion() {
1018 let arrow_array =
1019 TimestampMicrosecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
1020 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1021
1022 let arrow_array_non_null =
1023 TimestampMicrosecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
1024 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1025
1026 assert_eq!(vortex_array.len(), 4);
1027 assert_eq!(vortex_array_non_null.len(), 4);
1028 }
1029
1030 #[test]
1031 fn test_timestamp_timezone_microsecond_array_conversion() {
1032 let arrow_array =
1033 TimestampMicrosecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)])
1034 .with_timezone("UTC");
1035 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1036
1037 let arrow_array_non_null =
1038 TimestampMicrosecondArray::from(vec![1000_i64, 2000, 3000, 4000]).with_timezone("UTC");
1039 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1040
1041 assert_eq!(vortex_array.len(), 4);
1042 assert_eq!(
1043 vortex_array.dtype(),
1044 &DType::Extension(Arc::new(ExtDType::new(
1045 TIMESTAMP_ID.clone(),
1046 Arc::new(DType::Primitive(PType::I64, Nullability::Nullable)),
1047 Some(
1048 TemporalMetadata::Timestamp(TimeUnit::Microseconds, Some("UTC".to_string()))
1049 .into()
1050 )
1051 )))
1052 );
1053 assert_eq!(vortex_array_non_null.len(), 4);
1054 assert_eq!(
1055 vortex_array_non_null.dtype(),
1056 &DType::Extension(Arc::new(ExtDType::new(
1057 TIMESTAMP_ID.clone(),
1058 Arc::new(DType::Primitive(PType::I64, Nullability::NonNullable)),
1059 Some(
1060 TemporalMetadata::Timestamp(TimeUnit::Microseconds, Some("UTC".to_string()))
1061 .into()
1062 )
1063 )))
1064 );
1065 }
1066
1067 #[test]
1068 fn test_timestamp_nanosecond_array_conversion() {
1069 let arrow_array =
1070 TimestampNanosecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
1071 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1072
1073 let arrow_array_non_null = TimestampNanosecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
1074 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1075
1076 assert_eq!(vortex_array.len(), 4);
1077 assert_eq!(vortex_array_non_null.len(), 4);
1078 }
1079
1080 #[test]
1081 fn test_time32_second_array_conversion() {
1082 let arrow_array = Time32SecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
1083 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1084
1085 let arrow_array_non_null = Time32SecondArray::from(vec![1000_i32, 2000, 3000, 4000]);
1086 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1087
1088 assert_eq!(vortex_array.len(), 4);
1089 assert_eq!(vortex_array_non_null.len(), 4);
1090
1091 let temporal_array = TemporalArray::try_from(vortex_array.clone()).unwrap();
1093 assert_eq!(
1094 temporal_array.temporal_metadata().time_unit(),
1095 TimeUnit::Seconds
1096 );
1097
1098 let temporal_array_non_null =
1099 TemporalArray::try_from(vortex_array_non_null.clone()).unwrap();
1100 assert_eq!(
1101 temporal_array_non_null.temporal_metadata().time_unit(),
1102 TimeUnit::Seconds
1103 );
1104 }
1105
1106 #[test]
1107 fn test_time32_millisecond_array_conversion() {
1108 let arrow_array =
1109 Time32MillisecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
1110 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1111
1112 let arrow_array_non_null = Time32MillisecondArray::from(vec![1000_i32, 2000, 3000, 4000]);
1113 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1114
1115 assert_eq!(vortex_array.len(), 4);
1116 assert_eq!(vortex_array_non_null.len(), 4);
1117 }
1118
1119 #[test]
1120 fn test_time64_microsecond_array_conversion() {
1121 let arrow_array =
1122 Time64MicrosecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
1123 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1124
1125 let arrow_array_non_null = Time64MicrosecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
1126 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1127
1128 assert_eq!(vortex_array.len(), 4);
1129 assert_eq!(vortex_array_non_null.len(), 4);
1130 }
1131
1132 #[test]
1133 fn test_time64_nanosecond_array_conversion() {
1134 let arrow_array =
1135 Time64NanosecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
1136 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1137
1138 let arrow_array_non_null = Time64NanosecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
1139 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1140
1141 assert_eq!(vortex_array.len(), 4);
1142 assert_eq!(vortex_array_non_null.len(), 4);
1143 }
1144
1145 #[test]
1146 fn test_date32_array_conversion() {
1147 let arrow_array = Date32Array::from(vec![Some(18000), None, Some(18002), Some(18003)]);
1148 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1149
1150 let arrow_array_non_null = Date32Array::from(vec![18000_i32, 18001, 18002, 18003]);
1151 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1152
1153 assert_eq!(vortex_array.len(), 4);
1154 assert_eq!(vortex_array_non_null.len(), 4);
1155 }
1156
1157 #[test]
1158 fn test_date64_array_conversion() {
1159 let arrow_array = Date64Array::from(vec![
1160 Some(1555200000000),
1161 None,
1162 Some(1555286400000),
1163 Some(1555372800000),
1164 ]);
1165 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1166
1167 let arrow_array_non_null = Date64Array::from(vec![
1168 1555200000000_i64,
1169 1555213600000,
1170 1555286400000,
1171 1555372800000,
1172 ]);
1173 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1174
1175 assert_eq!(vortex_array.len(), 4);
1176 assert_eq!(vortex_array_non_null.len(), 4);
1177 }
1178
1179 #[test]
1181 fn test_utf8_array_conversion() {
1182 let arrow_array = StringArray::from(vec![Some("hello"), None, Some("world"), Some("test")]);
1183 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1184
1185 let arrow_array_non_null = StringArray::from(vec!["hello", "world", "test", "vortex"]);
1186 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1187
1188 assert_eq!(vortex_array.len(), 4);
1189 assert_eq!(vortex_array_non_null.len(), 4);
1190
1191 let varbin_array = vortex_array.as_::<VarBinVTable>();
1193 assert_eq!(varbin_array.dtype(), &DType::Utf8(true.into()));
1194
1195 let varbin_array_non_null = vortex_array_non_null.as_::<VarBinVTable>();
1196 assert_eq!(varbin_array_non_null.dtype(), &DType::Utf8(false.into()));
1197 }
1198
1199 #[test]
1200 fn test_large_utf8_array_conversion() {
1201 let arrow_array =
1202 LargeStringArray::from(vec![Some("hello"), None, Some("world"), Some("test")]);
1203 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1204
1205 let arrow_array_non_null = LargeStringArray::from(vec!["hello", "world", "test", "vortex"]);
1206 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1207
1208 assert_eq!(vortex_array.len(), 4);
1209 assert_eq!(vortex_array_non_null.len(), 4);
1210 }
1211
1212 #[test]
1213 fn test_binary_array_conversion() {
1214 let arrow_array = BinaryArray::from(vec![
1215 Some("hello".as_bytes()),
1216 None,
1217 Some("world".as_bytes()),
1218 Some("test".as_bytes()),
1219 ]);
1220 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1221
1222 let arrow_array_non_null = BinaryArray::from(vec![
1223 "hello".as_bytes(),
1224 "world".as_bytes(),
1225 "test".as_bytes(),
1226 "vortex".as_bytes(),
1227 ]);
1228 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1229
1230 assert_eq!(vortex_array.len(), 4);
1231 assert_eq!(vortex_array_non_null.len(), 4);
1232 }
1233
1234 #[test]
1235 fn test_large_binary_array_conversion() {
1236 let arrow_array = LargeBinaryArray::from(vec![
1237 Some("hello".as_bytes()),
1238 None,
1239 Some("world".as_bytes()),
1240 Some("test".as_bytes()),
1241 ]);
1242 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1243
1244 let arrow_array_non_null = LargeBinaryArray::from(vec![
1245 "hello".as_bytes(),
1246 "world".as_bytes(),
1247 "test".as_bytes(),
1248 "vortex".as_bytes(),
1249 ]);
1250 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1251
1252 assert_eq!(vortex_array.len(), 4);
1253 assert_eq!(vortex_array_non_null.len(), 4);
1254 }
1255
1256 #[test]
1257 fn test_utf8_view_array_conversion() {
1258 let mut builder = StringViewBuilder::new();
1259 builder.append_value("hello");
1260 builder.append_null();
1261 builder.append_value("world");
1262 builder.append_value("test");
1263 let arrow_array = builder.finish();
1264 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1265
1266 let mut builder_non_null = StringViewBuilder::new();
1267 builder_non_null.append_value("hello");
1268 builder_non_null.append_value("world");
1269 builder_non_null.append_value("test");
1270 builder_non_null.append_value("vortex");
1271 let arrow_array_non_null = builder_non_null.finish();
1272 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1273
1274 assert_eq!(vortex_array.len(), 4);
1275 assert_eq!(vortex_array_non_null.len(), 4);
1276
1277 let varbin_view_array = vortex_array.as_::<VarBinViewVTable>();
1279 assert_eq!(
1280 varbin_view_array.buffers().len(),
1281 arrow_array.data_buffers().len()
1282 );
1283 assert_eq!(varbin_view_array.dtype(), &DType::Utf8(true.into()));
1284
1285 let varbin_view_array_non_null = vortex_array_non_null.as_::<VarBinViewVTable>();
1286 assert_eq!(
1287 varbin_view_array_non_null.buffers().len(),
1288 arrow_array_non_null.data_buffers().len()
1289 );
1290 assert_eq!(
1291 varbin_view_array_non_null.dtype(),
1292 &DType::Utf8(false.into())
1293 );
1294 }
1295
1296 #[test]
1297 fn test_binary_view_array_conversion() {
1298 let mut builder = BinaryViewBuilder::new();
1299 builder.append_value(b"hello");
1300 builder.append_null();
1301 builder.append_value(b"world");
1302 builder.append_value(b"test");
1303 let arrow_array = builder.finish();
1304 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1305
1306 let mut builder_non_null = BinaryViewBuilder::new();
1307 builder_non_null.append_value(b"hello");
1308 builder_non_null.append_value(b"world");
1309 builder_non_null.append_value(b"test");
1310 builder_non_null.append_value(b"vortex");
1311 let arrow_array_non_null = builder_non_null.finish();
1312 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1313
1314 assert_eq!(vortex_array.len(), 4);
1315 assert_eq!(vortex_array_non_null.len(), 4);
1316
1317 let varbin_view_array = vortex_array.as_::<VarBinViewVTable>();
1319 assert_eq!(
1320 varbin_view_array.buffers().len(),
1321 arrow_array.data_buffers().len()
1322 );
1323 assert_eq!(varbin_view_array.dtype(), &DType::Binary(true.into()));
1324
1325 let varbin_view_array_non_null = vortex_array_non_null.as_::<VarBinViewVTable>();
1326 assert_eq!(
1327 varbin_view_array_non_null.buffers().len(),
1328 arrow_array_non_null.data_buffers().len()
1329 );
1330 assert_eq!(
1331 varbin_view_array_non_null.dtype(),
1332 &DType::Binary(false.into())
1333 );
1334 }
1335
1336 #[test]
1338 fn test_boolean_array_conversion() {
1339 let arrow_array = BooleanArray::from(vec![Some(true), None, Some(false), Some(true)]);
1340 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1341
1342 let arrow_array_non_null = BooleanArray::from(vec![true, false, true, false]);
1343 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1344
1345 assert_eq!(vortex_array.len(), 4);
1346 assert_eq!(vortex_array_non_null.len(), 4);
1347 }
1348
1349 #[test]
1351 fn test_struct_array_conversion() {
1352 let fields = vec![
1353 Field::new("field1", DataType::Int32, true),
1354 Field::new("field2", DataType::Utf8, false),
1355 ];
1356 let schema = Fields::from(fields);
1357
1358 let field1_data = Int32Array::from(vec![Some(1), None, Some(3)]);
1359 let field2_data = StringArray::from(vec!["a", "b", "c"]);
1360
1361 let arrow_array = StructArray::new(
1362 schema.clone(),
1363 vec![Arc::new(field1_data), Arc::new(field2_data)],
1364 None,
1365 );
1366
1367 let vortex_array = ArrayRef::from_arrow(&arrow_array, false);
1368 assert_eq!(vortex_array.len(), 3);
1369
1370 let struct_vortex_array = vortex_array.as_::<StructVTable>();
1372 assert_eq!(struct_vortex_array.names().len(), 2);
1373 assert_eq!(struct_vortex_array.names()[0], "field1");
1374 assert_eq!(struct_vortex_array.names()[1], "field2");
1375
1376 let nullable_array = StructArray::new(
1378 schema,
1379 vec![
1380 Arc::new(Int32Array::from(vec![Some(1), None, Some(3)])),
1381 Arc::new(StringArray::from(vec!["a", "b", "c"])),
1382 ],
1383 Some(arrow_buffer::NullBuffer::new(BooleanBuffer::from(vec![
1384 true, false, true,
1385 ]))),
1386 );
1387
1388 let vortex_nullable_array = ArrayRef::from_arrow(&nullable_array, true);
1389 assert_eq!(vortex_nullable_array.len(), 3);
1390
1391 let struct_vortex_nullable_array = vortex_nullable_array.as_::<StructVTable>();
1393 assert_eq!(struct_vortex_nullable_array.names().len(), 2);
1394 assert_eq!(struct_vortex_nullable_array.names()[0], "field1");
1395 assert_eq!(struct_vortex_nullable_array.names()[1], "field2");
1396 }
1397
1398 #[test]
1400 fn test_list_array_conversion() {
1401 let mut builder = ListBuilder::new(Int32Builder::new());
1402 builder.append_value([Some(1), None, Some(3)]);
1403 builder.append_null();
1404 builder.append_value([Some(4), Some(5)]);
1405 let arrow_array = builder.finish();
1406
1407 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1408 assert_eq!(vortex_array.len(), 3);
1409
1410 let list_vortex_array = vortex_array.as_::<ListVTable>();
1412 let offsets_array = list_vortex_array.offsets().as_::<PrimitiveVTable>();
1413 assert_eq!(offsets_array.len(), 4); assert_eq!(offsets_array.ptype(), PType::I32);
1415
1416 let mut builder_non_null = ListBuilder::new(Int32Builder::new());
1418 builder_non_null.append_value([Some(1), None, Some(3)]);
1419 builder_non_null.append_value([Some(4), Some(5)]);
1420 let arrow_array_non_null = builder_non_null.finish();
1421
1422 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1423 assert_eq!(vortex_array_non_null.len(), 2);
1424
1425 let list_vortex_array_non_null = vortex_array_non_null.as_::<ListVTable>();
1427 let offsets_array_non_null = list_vortex_array_non_null
1428 .offsets()
1429 .as_::<PrimitiveVTable>();
1430 assert_eq!(offsets_array_non_null.len(), 3); assert_eq!(offsets_array_non_null.ptype(), PType::I32);
1432 }
1433
1434 #[test]
1435 fn test_large_list_array_conversion() {
1436 let mut builder = LargeListBuilder::new(Int32Builder::new());
1437 builder.append_value([Some(1), None, Some(3)]);
1438 builder.append_null();
1439 builder.append_value([Some(4), Some(5)]);
1440 let arrow_array = builder.finish();
1441
1442 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1443 assert_eq!(vortex_array.len(), 3);
1444
1445 let list_vortex_array = vortex_array.as_::<ListVTable>();
1447 let offsets_array = list_vortex_array.offsets().as_::<PrimitiveVTable>();
1448 assert_eq!(offsets_array.len(), 4); assert_eq!(offsets_array.ptype(), PType::I64); let mut builder_non_null = LargeListBuilder::new(Int32Builder::new());
1453 builder_non_null.append_value([Some(1), None, Some(3)]);
1454 builder_non_null.append_value([Some(4), Some(5)]);
1455 let arrow_array_non_null = builder_non_null.finish();
1456
1457 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1458 assert_eq!(vortex_array_non_null.len(), 2);
1459
1460 let list_vortex_array_non_null = vortex_array_non_null.as_::<ListVTable>();
1462 let offsets_array_non_null = list_vortex_array_non_null
1463 .offsets()
1464 .as_::<PrimitiveVTable>();
1465 assert_eq!(offsets_array_non_null.len(), 3); assert_eq!(offsets_array_non_null.ptype(), PType::I64); }
1468
1469 #[test]
1470 fn test_fixed_size_list_array_conversion() {
1471 let values = Int32Array::from(vec![
1473 Some(1),
1474 Some(2),
1475 Some(3), Some(4),
1477 None,
1478 Some(6), Some(7),
1480 Some(8),
1481 Some(9), Some(10),
1483 Some(11),
1484 Some(12), ]);
1486
1487 let field = Arc::new(Field::new("item", DataType::Int32, true));
1489 let arrow_array =
1490 ArrowFixedSizeListArray::try_new(field.clone(), 3, Arc::new(values), None).unwrap();
1491 let vortex_array = ArrayRef::from_arrow(&arrow_array, false);
1492
1493 assert_eq!(vortex_array.len(), 4);
1494
1495 let fsl_vortex_array = vortex_array.as_::<FixedSizeListVTable>();
1497 assert_eq!(fsl_vortex_array.list_size(), 3);
1498 assert_eq!(fsl_vortex_array.elements().len(), 12); let values_nullable = Int32Array::from(vec![
1502 Some(1),
1503 Some(2),
1504 Some(3), Some(4),
1506 None,
1507 Some(6), Some(7),
1509 Some(8),
1510 Some(9), ]);
1512
1513 let null_buffer =
1515 arrow_buffer::NullBuffer::new(BooleanBuffer::from(vec![true, false, true]));
1516
1517 let arrow_array_nullable = ArrowFixedSizeListArray::try_new(
1518 field,
1519 3,
1520 Arc::new(values_nullable),
1521 Some(null_buffer),
1522 )
1523 .unwrap();
1524 let vortex_array_nullable = ArrayRef::from_arrow(&arrow_array_nullable, true);
1525
1526 assert_eq!(vortex_array_nullable.len(), 3);
1527
1528 let fsl_vortex_array_nullable = vortex_array_nullable.as_::<FixedSizeListVTable>();
1530 assert_eq!(fsl_vortex_array_nullable.list_size(), 3);
1531 assert_eq!(fsl_vortex_array_nullable.elements().len(), 9); }
1533
1534 #[test]
1535 fn test_list_view_array_conversion() {
1536 let values = Int32Array::from(vec![
1538 Some(1),
1539 Some(2),
1540 Some(3), Some(4),
1542 Some(5), Some(6), Some(7),
1545 Some(8),
1546 Some(9),
1547 Some(10), ]);
1549
1550 let offsets = ScalarBuffer::from(vec![0i32, 3, 5, 6]);
1552 let sizes = ScalarBuffer::from(vec![3i32, 2, 1, 4]);
1553
1554 let field = Arc::new(Field::new("item", DataType::Int32, true));
1555 let arrow_array = GenericListViewArray::try_new(
1556 field.clone(),
1557 offsets.clone(),
1558 sizes.clone(),
1559 Arc::new(values.clone()),
1560 None,
1561 )
1562 .unwrap();
1563
1564 let vortex_array = ArrayRef::from_arrow(&arrow_array, false);
1565 assert_eq!(vortex_array.len(), 4);
1566
1567 let list_view_vortex_array = vortex_array.as_::<ListViewVTable>();
1569 let offsets_array = list_view_vortex_array.offsets().as_::<PrimitiveVTable>();
1570 let sizes_array = list_view_vortex_array.sizes().as_::<PrimitiveVTable>();
1571
1572 assert_eq!(offsets_array.len(), 4);
1573 assert_eq!(offsets_array.ptype(), PType::I32);
1574 assert_eq!(sizes_array.len(), 4);
1575 assert_eq!(sizes_array.ptype(), PType::I32);
1576
1577 let null_buffer =
1579 arrow_buffer::NullBuffer::new(BooleanBuffer::from(vec![true, false, true, true]));
1580
1581 let arrow_array_nullable = GenericListViewArray::try_new(
1582 field.clone(),
1583 offsets,
1584 sizes,
1585 Arc::new(values.clone()),
1586 Some(null_buffer),
1587 )
1588 .unwrap();
1589
1590 let vortex_array_nullable = ArrayRef::from_arrow(&arrow_array_nullable, true);
1591 assert_eq!(vortex_array_nullable.len(), 4);
1592
1593 let large_offsets = ScalarBuffer::from(vec![0i64, 3, 5, 6]);
1595 let large_sizes = ScalarBuffer::from(vec![3i64, 2, 1, 4]);
1596
1597 let large_arrow_array = GenericListViewArray::try_new(
1598 field,
1599 large_offsets,
1600 large_sizes,
1601 Arc::new(values),
1602 None,
1603 )
1604 .unwrap();
1605
1606 let large_vortex_array = ArrayRef::from_arrow(&large_arrow_array, false);
1607 assert_eq!(large_vortex_array.len(), 4);
1608
1609 let large_list_view_vortex_array = large_vortex_array.as_::<ListViewVTable>();
1611 let large_offsets_array = large_list_view_vortex_array
1612 .offsets()
1613 .as_::<PrimitiveVTable>();
1614 let large_sizes_array = large_list_view_vortex_array
1615 .sizes()
1616 .as_::<PrimitiveVTable>();
1617
1618 assert_eq!(large_offsets_array.len(), 4);
1619 assert_eq!(large_offsets_array.ptype(), PType::I64); assert_eq!(large_sizes_array.len(), 4);
1621 assert_eq!(large_sizes_array.ptype(), PType::I64); }
1623
1624 #[test]
1626 fn test_null_array_conversion() {
1627 let arrow_array = NullArray::new(5);
1628 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1629 assert_eq!(vortex_array.len(), 5);
1630 }
1631
1632 #[test]
1634 fn test_arrow_buffer_conversion() {
1635 let data = vec![1u8, 2, 3, 4, 5];
1636 let arrow_buffer = ArrowBuffer::from_vec(data);
1637 let vortex_array = arrow_buffer.into_array();
1638 assert_eq!(vortex_array.len(), 5);
1639 }
1640
1641 #[test]
1642 fn test_boolean_buffer_conversion() {
1643 let data = vec![true, false, true, false, true];
1644 let boolean_buffer = BooleanBuffer::from(data);
1645 let vortex_array = boolean_buffer.into_array();
1646 assert_eq!(vortex_array.len(), 5);
1647 }
1648
1649 #[test]
1650 fn test_scalar_buffer_conversion() {
1651 let data = vec![1i32, 2, 3, 4, 5];
1652 let scalar_buffer = ScalarBuffer::from(data);
1653 let vortex_array = scalar_buffer.into_array();
1654 assert_eq!(vortex_array.len(), 5);
1655 }
1656
1657 #[test]
1658 fn test_offset_buffer_conversion() {
1659 let data = vec![0i32, 2, 5, 8, 10];
1660 let offset_buffer = OffsetBuffer::new(ScalarBuffer::from(data));
1661 let vortex_array = offset_buffer.into_array();
1662 assert_eq!(vortex_array.len(), 5);
1663 }
1664
1665 #[test]
1667 fn test_record_batch_conversion() {
1668 let schema = Arc::new(Schema::new(vec![
1669 Field::new("field1", DataType::Int32, false),
1670 Field::new("field2", DataType::Utf8, false),
1671 ]));
1672
1673 let field1_data = Arc::new(Int32Array::from(vec![1, 2, 3, 4]));
1674 let field2_data = Arc::new(StringArray::from(vec!["a", "b", "c", "d"]));
1675
1676 let record_batch = RecordBatch::try_new(schema, vec![field1_data, field2_data]).unwrap();
1677
1678 let vortex_array = ArrayRef::from_arrow(record_batch, false);
1679 assert_eq!(vortex_array.len(), 4);
1680
1681 let schema = Arc::new(Schema::new(vec![
1683 Field::new("field1", DataType::Int32, false),
1684 Field::new("field2", DataType::Utf8, false),
1685 ]));
1686
1687 let field1_data = Arc::new(Int32Array::from(vec![1, 2, 3, 4]));
1688 let field2_data = Arc::new(StringArray::from(vec!["a", "b", "c", "d"]));
1689
1690 let record_batch = RecordBatch::try_new(schema, vec![field1_data, field2_data]).unwrap();
1691
1692 let vortex_array = ArrayRef::from_arrow(&record_batch, false);
1693 assert_eq!(vortex_array.len(), 4);
1694 }
1695
1696 #[test]
1698 fn test_dyn_array_conversion() {
1699 let int_array = Int32Array::from(vec![1, 2, 3, 4]);
1700 let dyn_array: &dyn ArrowArray = &int_array;
1701 let vortex_array = ArrayRef::from_arrow(dyn_array, false);
1702 assert_eq!(vortex_array.len(), 4);
1703
1704 let string_array = StringArray::from(vec!["a", "b", "c"]);
1705 let dyn_array: &dyn ArrowArray = &string_array;
1706 let vortex_array = ArrayRef::from_arrow(dyn_array, false);
1707 assert_eq!(vortex_array.len(), 3);
1708
1709 let bool_array = BooleanArray::from(vec![true, false, true]);
1710 let dyn_array: &dyn ArrowArray = &bool_array;
1711 let vortex_array = ArrayRef::from_arrow(dyn_array, false);
1712 assert_eq!(vortex_array.len(), 3);
1713 }
1714
1715 #[test]
1717 pub fn nullable_may_contain_non_nullable() {
1718 let null_struct_array_with_non_nullable_field = new_null_array(
1719 &DataType::Struct(Fields::from(vec![Field::new(
1720 "non_nullable_inner",
1721 DataType::Int32,
1722 false,
1723 )])),
1724 1,
1725 );
1726 ArrayRef::from_arrow(null_struct_array_with_non_nullable_field.as_ref(), true);
1727 }
1728
1729 #[test]
1730 pub fn nullable_may_contain_deeply_nested_non_nullable() {
1731 let null_struct_array_with_non_nullable_field = new_null_array(
1732 &DataType::Struct(Fields::from(vec![Field::new(
1733 "non_nullable_inner",
1734 DataType::Struct(Fields::from(vec![Field::new(
1735 "non_nullable_deeper_inner",
1736 DataType::Int32,
1737 false,
1738 )])),
1739 false,
1740 )])),
1741 1,
1742 );
1743 ArrayRef::from_arrow(null_struct_array_with_non_nullable_field.as_ref(), true);
1744 }
1745
1746 #[test]
1747 #[should_panic]
1748 pub fn cannot_handle_nullable_struct_containing_non_nullable_dictionary() {
1749 let null_struct_array_with_non_nullable_field = new_null_array(
1750 &DataType::Struct(Fields::from(vec![Field::new(
1751 "non_nullable_deeper_inner",
1752 DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8)),
1753 false,
1754 )])),
1755 1,
1756 );
1757
1758 ArrayRef::from_arrow(null_struct_array_with_non_nullable_field.as_ref(), true);
1759 }
1760}