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