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