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