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, 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, Buffer, ByteBuffer};
26use vortex_dtype::datetime::TimeUnit;
27use vortex_dtype::{DType, DecimalDType, NativePType, PType};
28use vortex_error::{VortexExpect as _, vortex_panic};
29use vortex_scalar::i256;
30
31use crate::arrays::{
32 BoolArray, DecimalArray, FixedSizeListArray, ListArray, NullArray, PrimitiveArray, StructArray,
33 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_bool_buffer(self, 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: NativePType + 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: NativePType,
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_bool_buffer(value.values().clone(), nulls(value.nulls(), nullable))
255 .into_array()
256 }
257}
258
259fn remove_nulls(data: arrow_data::ArrayData) -> arrow_data::ArrayData {
261 if data.null_count() == 0 {
262 return data;
264 }
265
266 let children = match data.data_type() {
267 DataType::Struct(fields) => Some(
268 fields
269 .iter()
270 .zip(data.child_data().iter())
271 .map(|(field, child_data)| {
272 if field.is_nullable() {
273 child_data.clone()
274 } else {
275 remove_nulls(child_data.clone())
276 }
277 })
278 .collect_vec(),
279 ),
280 DataType::List(f)
281 | DataType::LargeList(f)
282 | DataType::ListView(f)
283 | DataType::LargeListView(f)
284 | DataType::FixedSizeList(f, _)
285 if !f.is_nullable() =>
286 {
287 assert_eq!(
289 data.child_data().len(),
290 1,
291 "List types should have one child"
292 );
293 Some(vec![remove_nulls(data.child_data()[0].clone())])
294 }
295 _ => None,
296 };
297
298 let mut builder = data.into_builder().nulls(None);
299 if let Some(children) = children {
300 builder = builder.child_data(children);
301 }
302 builder
303 .build()
304 .vortex_expect("reconstructing array without nulls")
305}
306
307impl FromArrowArray<&ArrowStructArray> for ArrayRef {
308 fn from_arrow(value: &ArrowStructArray, nullable: bool) -> Self {
309 StructArray::try_new(
310 value.column_names().iter().copied().collect(),
311 value
312 .columns()
313 .iter()
314 .zip(value.fields())
315 .map(|(c, field)| {
316 if c.null_count() > 0 && !field.is_nullable() {
319 let stripped = make_array(remove_nulls(c.into_data()));
320 Self::from_arrow(stripped.as_ref(), false)
321 } else {
322 Self::from_arrow(c.as_ref(), field.is_nullable())
323 }
324 })
325 .collect(),
326 value.len(),
327 nulls(value.nulls(), nullable),
328 )
329 .vortex_expect("Failed to convert Arrow StructArray to Vortex StructArray")
330 .into_array()
331 }
332}
333
334impl<O: OffsetSizeTrait + NativePType> FromArrowArray<&GenericListArray<O>> for ArrayRef {
335 fn from_arrow(value: &GenericListArray<O>, nullable: bool) -> Self {
336 let elem_nullable = match value.data_type() {
338 DataType::List(field) => field.is_nullable(),
339 DataType::LargeList(field) => field.is_nullable(),
340 dt => vortex_panic!("Invalid data type for ListArray: {dt}"),
341 };
342 ListArray::try_new(
343 Self::from_arrow(value.values().as_ref(), elem_nullable),
344 value.offsets().clone().into_array(),
346 nulls(value.nulls(), nullable),
347 )
348 .vortex_expect("Failed to convert Arrow ListArray to Vortex ListArray")
349 .into_array()
350 }
351}
352
353impl FromArrowArray<&ArrowFixedSizeListArray> for ArrayRef {
354 fn from_arrow(array: &ArrowFixedSizeListArray, nullable: bool) -> Self {
355 let DataType::FixedSizeList(field, list_size) = array.data_type() else {
356 vortex_panic!("Invalid data type for ListArray: {}", array.data_type());
357 };
358
359 FixedSizeListArray::try_new(
360 Self::from_arrow(array.values().as_ref(), field.is_nullable()),
361 *list_size as u32,
362 nulls(array.nulls(), nullable),
363 array.len(),
364 )
365 .vortex_expect("Failed to convert Arrow FixedSizeListArray to Vortex FixedSizeListArray")
366 .into_array()
367 }
368}
369
370impl FromArrowArray<&ArrowNullArray> for ArrayRef {
371 fn from_arrow(value: &ArrowNullArray, nullable: bool) -> Self {
372 assert!(nullable);
373 NullArray::new(value.len()).into_array()
374 }
375}
376
377fn nulls(nulls: Option<&NullBuffer>, nullable: bool) -> Validity {
378 if nullable {
379 nulls
380 .map(|nulls| {
381 if nulls.null_count() == nulls.len() {
382 Validity::AllInvalid
383 } else {
384 Validity::from(nulls.inner().clone())
385 }
386 })
387 .unwrap_or_else(|| Validity::AllValid)
388 } else {
389 assert!(nulls.map(|x| x.null_count() == 0).unwrap_or(true));
390 Validity::NonNullable
391 }
392}
393
394impl FromArrowArray<&dyn ArrowArray> for ArrayRef {
395 fn from_arrow(array: &dyn ArrowArray, nullable: bool) -> Self {
396 match array.data_type() {
397 DataType::Boolean => Self::from_arrow(array.as_boolean(), nullable),
398 DataType::UInt8 => Self::from_arrow(array.as_primitive::<UInt8Type>(), nullable),
399 DataType::UInt16 => Self::from_arrow(array.as_primitive::<UInt16Type>(), nullable),
400 DataType::UInt32 => Self::from_arrow(array.as_primitive::<UInt32Type>(), nullable),
401 DataType::UInt64 => Self::from_arrow(array.as_primitive::<UInt64Type>(), nullable),
402 DataType::Int8 => Self::from_arrow(array.as_primitive::<Int8Type>(), nullable),
403 DataType::Int16 => Self::from_arrow(array.as_primitive::<Int16Type>(), nullable),
404 DataType::Int32 => Self::from_arrow(array.as_primitive::<Int32Type>(), nullable),
405 DataType::Int64 => Self::from_arrow(array.as_primitive::<Int64Type>(), nullable),
406 DataType::Float16 => Self::from_arrow(array.as_primitive::<Float16Type>(), nullable),
407 DataType::Float32 => Self::from_arrow(array.as_primitive::<Float32Type>(), nullable),
408 DataType::Float64 => Self::from_arrow(array.as_primitive::<Float64Type>(), nullable),
409 DataType::Utf8 => Self::from_arrow(array.as_string::<i32>(), nullable),
410 DataType::LargeUtf8 => Self::from_arrow(array.as_string::<i64>(), nullable),
411 DataType::Binary => Self::from_arrow(array.as_binary::<i32>(), nullable),
412 DataType::LargeBinary => Self::from_arrow(array.as_binary::<i64>(), nullable),
413 DataType::BinaryView => Self::from_arrow(array.as_binary_view(), nullable),
414 DataType::Utf8View => Self::from_arrow(array.as_string_view(), nullable),
415 DataType::Struct(_) => Self::from_arrow(array.as_struct(), nullable),
416 DataType::List(_) => Self::from_arrow(array.as_list::<i32>(), nullable),
417 DataType::LargeList(_) => Self::from_arrow(array.as_list::<i64>(), nullable),
418 DataType::FixedSizeList(..) => Self::from_arrow(array.as_fixed_size_list(), nullable),
419 DataType::Null => Self::from_arrow(as_null_array(array), nullable),
420 DataType::Timestamp(u, _) => match u {
421 ArrowTimeUnit::Second => {
422 Self::from_arrow(array.as_primitive::<TimestampSecondType>(), nullable)
423 }
424 ArrowTimeUnit::Millisecond => {
425 Self::from_arrow(array.as_primitive::<TimestampMillisecondType>(), nullable)
426 }
427 ArrowTimeUnit::Microsecond => {
428 Self::from_arrow(array.as_primitive::<TimestampMicrosecondType>(), nullable)
429 }
430 ArrowTimeUnit::Nanosecond => {
431 Self::from_arrow(array.as_primitive::<TimestampNanosecondType>(), nullable)
432 }
433 },
434 DataType::Date32 => Self::from_arrow(array.as_primitive::<Date32Type>(), nullable),
435 DataType::Date64 => Self::from_arrow(array.as_primitive::<Date64Type>(), nullable),
436 DataType::Time32(u) => match u {
437 ArrowTimeUnit::Second => {
438 Self::from_arrow(array.as_primitive::<Time32SecondType>(), nullable)
439 }
440 ArrowTimeUnit::Millisecond => {
441 Self::from_arrow(array.as_primitive::<Time32MillisecondType>(), nullable)
442 }
443 ArrowTimeUnit::Microsecond | ArrowTimeUnit::Nanosecond => unreachable!(),
444 },
445 DataType::Time64(u) => match u {
446 ArrowTimeUnit::Microsecond => {
447 Self::from_arrow(array.as_primitive::<Time64MicrosecondType>(), nullable)
448 }
449 ArrowTimeUnit::Nanosecond => {
450 Self::from_arrow(array.as_primitive::<Time64NanosecondType>(), nullable)
451 }
452 ArrowTimeUnit::Second | ArrowTimeUnit::Millisecond => unreachable!(),
453 },
454 DataType::Decimal32(..) => {
455 Self::from_arrow(array.as_primitive::<Decimal32Type>(), nullable)
456 }
457 DataType::Decimal64(..) => {
458 Self::from_arrow(array.as_primitive::<Decimal64Type>(), nullable)
459 }
460 DataType::Decimal128(..) => {
461 Self::from_arrow(array.as_primitive::<Decimal128Type>(), nullable)
462 }
463 DataType::Decimal256(..) => {
464 Self::from_arrow(array.as_primitive::<Decimal256Type>(), nullable)
465 }
466 dt => vortex_panic!("Array encoding not implemented for Arrow data type {dt}"),
467 }
468 }
469}
470
471impl FromArrowArray<RecordBatch> for ArrayRef {
472 fn from_arrow(array: RecordBatch, nullable: bool) -> Self {
473 ArrayRef::from_arrow(&arrow_array::StructArray::from(array), nullable)
474 }
475}
476
477impl FromArrowArray<&RecordBatch> for ArrayRef {
478 fn from_arrow(array: &RecordBatch, nullable: bool) -> Self {
479 Self::from_arrow(array.clone(), nullable)
480 }
481}
482
483#[cfg(test)]
484mod tests {
485 use std::sync::Arc;
486
487 use arrow_array::builder::{
488 BinaryViewBuilder, Decimal128Builder, Decimal256Builder, Int32Builder, LargeListBuilder,
489 ListBuilder, StringViewBuilder,
490 };
491 use arrow_array::types::{ArrowPrimitiveType, Float16Type};
492 use arrow_array::{
493 Array as ArrowArray, BinaryArray, BooleanArray, Date32Array, Date64Array, Float32Array,
494 Float64Array, Int8Array, Int16Array, Int32Array, Int64Array, LargeBinaryArray,
495 LargeStringArray, NullArray, RecordBatch, StringArray, StructArray, Time32MillisecondArray,
496 Time32SecondArray, Time64MicrosecondArray, Time64NanosecondArray,
497 TimestampMicrosecondArray, TimestampMillisecondArray, TimestampNanosecondArray,
498 TimestampSecondArray, UInt8Array, UInt16Array, UInt32Array, UInt64Array, new_null_array,
499 };
500 use arrow_buffer::{BooleanBuffer, Buffer as ArrowBuffer, OffsetBuffer, ScalarBuffer};
501 use arrow_schema::{DataType, Field, Fields, Schema};
502 use vortex_dtype::datetime::{TIMESTAMP_ID, TemporalMetadata, TimeUnit};
503 use vortex_dtype::{DType, ExtDType, Nullability, PType};
504
505 use crate::arrays::{
506 DecimalVTable, ListVTable, PrimitiveVTable, StructVTable, TemporalArray, VarBinVTable,
507 VarBinViewVTable,
508 };
509 use crate::arrow::FromArrowArray as _;
510 use crate::{ArrayRef, IntoArray};
511
512 #[test]
514 fn test_int8_array_conversion() {
515 let arrow_array = Int8Array::from(vec![Some(1), None, Some(3), Some(4)]);
516 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
517
518 let arrow_array_non_null = Int8Array::from(vec![1, 2, 3, 4]);
519 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
520
521 assert_eq!(vortex_array.len(), 4);
522 assert_eq!(vortex_array_non_null.len(), 4);
523
524 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
526 assert_eq!(primitive_array.ptype(), PType::I8);
527
528 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
529 assert_eq!(primitive_array_non_null.ptype(), PType::I8);
530 }
531
532 #[test]
533 fn test_int16_array_conversion() {
534 let arrow_array = Int16Array::from(vec![Some(100), None, Some(300), Some(400)]);
535 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
536
537 let arrow_array_non_null = Int16Array::from(vec![100, 200, 300, 400]);
538 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
539
540 assert_eq!(vortex_array.len(), 4);
541 assert_eq!(vortex_array_non_null.len(), 4);
542
543 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
545 assert_eq!(primitive_array.ptype(), PType::I16);
546
547 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
548 assert_eq!(primitive_array_non_null.ptype(), PType::I16);
549 }
550
551 #[test]
552 fn test_int32_array_conversion() {
553 let arrow_array = Int32Array::from(vec![Some(1000), None, Some(3000), Some(4000)]);
554 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
555
556 let arrow_array_non_null = Int32Array::from(vec![1000, 2000, 3000, 4000]);
557 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
558
559 assert_eq!(vortex_array.len(), 4);
560 assert_eq!(vortex_array_non_null.len(), 4);
561
562 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
564 assert_eq!(primitive_array.ptype(), PType::I32);
565
566 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
567 assert_eq!(primitive_array_non_null.ptype(), PType::I32);
568 }
569
570 #[test]
571 fn test_int64_array_conversion() {
572 let arrow_array = Int64Array::from(vec![Some(10000), None, Some(30000), Some(40000)]);
573 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
574
575 let arrow_array_non_null = Int64Array::from(vec![10000_i64, 20000, 30000, 40000]);
576 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
577
578 assert_eq!(vortex_array.len(), 4);
579 assert_eq!(vortex_array_non_null.len(), 4);
580
581 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
583 assert_eq!(primitive_array.ptype(), PType::I64);
584
585 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
586 assert_eq!(primitive_array_non_null.ptype(), PType::I64);
587 }
588
589 #[test]
590 fn test_uint8_array_conversion() {
591 let arrow_array = UInt8Array::from(vec![Some(1), None, Some(3), Some(4)]);
592 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
593
594 let arrow_array_non_null = UInt8Array::from(vec![1_u8, 2, 3, 4]);
595 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
596
597 assert_eq!(vortex_array.len(), 4);
598 assert_eq!(vortex_array_non_null.len(), 4);
599
600 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
602 assert_eq!(primitive_array.ptype(), PType::U8);
603
604 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
605 assert_eq!(primitive_array_non_null.ptype(), PType::U8);
606 }
607
608 #[test]
609 fn test_uint16_array_conversion() {
610 let arrow_array = UInt16Array::from(vec![Some(100), None, Some(300), Some(400)]);
611 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
612
613 let arrow_array_non_null = UInt16Array::from(vec![100_u16, 200, 300, 400]);
614 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
615
616 assert_eq!(vortex_array.len(), 4);
617 assert_eq!(vortex_array_non_null.len(), 4);
618
619 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
621 assert_eq!(primitive_array.ptype(), PType::U16);
622
623 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
624 assert_eq!(primitive_array_non_null.ptype(), PType::U16);
625 }
626
627 #[test]
628 fn test_uint32_array_conversion() {
629 let arrow_array = UInt32Array::from(vec![Some(1000), None, Some(3000), Some(4000)]);
630 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
631
632 let arrow_array_non_null = UInt32Array::from(vec![1000_u32, 2000, 3000, 4000]);
633 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
634
635 assert_eq!(vortex_array.len(), 4);
636 assert_eq!(vortex_array_non_null.len(), 4);
637
638 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
640 assert_eq!(primitive_array.ptype(), PType::U32);
641
642 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
643 assert_eq!(primitive_array_non_null.ptype(), PType::U32);
644 }
645
646 #[test]
647 fn test_uint64_array_conversion() {
648 let arrow_array = UInt64Array::from(vec![Some(10000), None, Some(30000), Some(40000)]);
649 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
650
651 let arrow_array_non_null = UInt64Array::from(vec![10000_u64, 20000, 30000, 40000]);
652 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
653
654 assert_eq!(vortex_array.len(), 4);
655 assert_eq!(vortex_array_non_null.len(), 4);
656
657 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
659 assert_eq!(primitive_array.ptype(), PType::U64);
660
661 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
662 assert_eq!(primitive_array_non_null.ptype(), PType::U64);
663 }
664
665 #[test]
666 fn test_float16_array_conversion() {
667 let values = vec![
668 Some(<Float16Type as ArrowPrimitiveType>::Native::from_f32(1.5)),
669 None,
670 Some(<Float16Type as ArrowPrimitiveType>::Native::from_f32(3.5)),
671 ];
672 let arrow_array = arrow_array::PrimitiveArray::<Float16Type>::from(values);
673 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
674
675 let non_null_values = vec![
676 <Float16Type as ArrowPrimitiveType>::Native::from_f32(1.5),
677 <Float16Type as ArrowPrimitiveType>::Native::from_f32(2.5),
678 ];
679 let arrow_array_non_null =
680 arrow_array::PrimitiveArray::<Float16Type>::from(non_null_values);
681 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
682
683 assert_eq!(vortex_array.len(), 3);
684 assert_eq!(vortex_array_non_null.len(), 2);
685
686 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
688 assert_eq!(primitive_array.ptype(), PType::F16);
689
690 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
691 assert_eq!(primitive_array_non_null.ptype(), PType::F16);
692 }
693
694 #[test]
695 fn test_float32_array_conversion() {
696 let arrow_array = Float32Array::from(vec![Some(1.5), None, Some(3.5), Some(4.5)]);
697 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
698
699 let arrow_array_non_null = Float32Array::from(vec![1.5_f32, 2.5, 3.5, 4.5]);
700 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
701
702 assert_eq!(vortex_array.len(), 4);
703 assert_eq!(vortex_array_non_null.len(), 4);
704
705 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
707 assert_eq!(primitive_array.ptype(), PType::F32);
708
709 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
710 assert_eq!(primitive_array_non_null.ptype(), PType::F32);
711 }
712
713 #[test]
714 fn test_float64_array_conversion() {
715 let arrow_array = Float64Array::from(vec![Some(1.5), None, Some(3.5), Some(4.5)]);
716 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
717
718 let arrow_array_non_null = Float64Array::from(vec![1.5_f64, 2.5, 3.5, 4.5]);
719 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
720
721 assert_eq!(vortex_array.len(), 4);
722 assert_eq!(vortex_array_non_null.len(), 4);
723
724 let primitive_array = vortex_array.as_::<PrimitiveVTable>();
726 assert_eq!(primitive_array.ptype(), PType::F64);
727
728 let primitive_array_non_null = vortex_array_non_null.as_::<PrimitiveVTable>();
729 assert_eq!(primitive_array_non_null.ptype(), PType::F64);
730 }
731
732 #[test]
734 fn test_decimal128_array_conversion() {
735 let mut builder = Decimal128Builder::with_capacity(4);
736 builder.append_value(12345);
737 builder.append_null();
738 builder.append_value(67890);
739 builder.append_value(11111);
740 let decimal_array = builder.finish().with_precision_and_scale(10, 2).unwrap();
741
742 let vortex_array = ArrayRef::from_arrow(&decimal_array, true);
743 assert_eq!(vortex_array.len(), 4);
744
745 let mut builder_non_null = Decimal128Builder::with_capacity(3);
746 builder_non_null.append_value(12345);
747 builder_non_null.append_value(67890);
748 builder_non_null.append_value(11111);
749 let decimal_array_non_null = builder_non_null
750 .finish()
751 .with_precision_and_scale(10, 2)
752 .unwrap();
753
754 let vortex_array_non_null = ArrayRef::from_arrow(&decimal_array_non_null, false);
755 assert_eq!(vortex_array_non_null.len(), 3);
756
757 let decimal_vortex_array = vortex_array.as_::<DecimalVTable>();
759 assert_eq!(decimal_vortex_array.decimal_dtype().precision(), 10);
760 assert_eq!(decimal_vortex_array.decimal_dtype().scale(), 2);
761
762 let decimal_vortex_array_non_null = vortex_array_non_null.as_::<DecimalVTable>();
763 assert_eq!(
764 decimal_vortex_array_non_null.decimal_dtype().precision(),
765 10
766 );
767 assert_eq!(decimal_vortex_array_non_null.decimal_dtype().scale(), 2);
768 }
769
770 #[test]
771 fn test_decimal256_array_conversion() {
772 let mut builder = Decimal256Builder::with_capacity(4);
773 builder.append_value(arrow_buffer::i256::from_i128(12345));
774 builder.append_null();
775 builder.append_value(arrow_buffer::i256::from_i128(67890));
776 builder.append_value(arrow_buffer::i256::from_i128(11111));
777 let decimal_array = builder.finish().with_precision_and_scale(38, 10).unwrap();
778
779 let vortex_array = ArrayRef::from_arrow(&decimal_array, true);
780 assert_eq!(vortex_array.len(), 4);
781
782 let mut builder_non_null = Decimal256Builder::with_capacity(3);
783 builder_non_null.append_value(arrow_buffer::i256::from_i128(12345));
784 builder_non_null.append_value(arrow_buffer::i256::from_i128(67890));
785 builder_non_null.append_value(arrow_buffer::i256::from_i128(11111));
786 let decimal_array_non_null = builder_non_null
787 .finish()
788 .with_precision_and_scale(38, 10)
789 .unwrap();
790
791 let vortex_array_non_null = ArrayRef::from_arrow(&decimal_array_non_null, false);
792 assert_eq!(vortex_array_non_null.len(), 3);
793
794 let decimal_vortex_array = vortex_array.as_::<DecimalVTable>();
796 assert_eq!(decimal_vortex_array.decimal_dtype().precision(), 38);
797 assert_eq!(decimal_vortex_array.decimal_dtype().scale(), 10);
798
799 let decimal_vortex_array_non_null = vortex_array_non_null.as_::<DecimalVTable>();
800 assert_eq!(
801 decimal_vortex_array_non_null.decimal_dtype().precision(),
802 38
803 );
804 assert_eq!(decimal_vortex_array_non_null.decimal_dtype().scale(), 10);
805 }
806
807 #[test]
809 fn test_timestamp_second_array_conversion() {
810 let arrow_array =
811 TimestampSecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
812 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
813
814 let arrow_array_non_null = TimestampSecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
815 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
816
817 assert_eq!(vortex_array.len(), 4);
818 assert_eq!(vortex_array_non_null.len(), 4);
819
820 let temporal_array = TemporalArray::try_from(vortex_array.clone()).unwrap();
822 assert_eq!(
823 temporal_array.temporal_metadata().time_unit(),
824 TimeUnit::Seconds
825 );
826
827 let temporal_array_non_null =
828 TemporalArray::try_from(vortex_array_non_null.clone()).unwrap();
829 assert_eq!(
830 temporal_array_non_null.temporal_metadata().time_unit(),
831 TimeUnit::Seconds
832 );
833 }
834
835 #[test]
836 fn test_timestamp_millisecond_array_conversion() {
837 let arrow_array =
838 TimestampMillisecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
839 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
840
841 let arrow_array_non_null =
842 TimestampMillisecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
843 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
844
845 assert_eq!(vortex_array.len(), 4);
846 assert_eq!(vortex_array_non_null.len(), 4);
847 }
848
849 #[test]
850 fn test_timestamp_microsecond_array_conversion() {
851 let arrow_array =
852 TimestampMicrosecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
853 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
854
855 let arrow_array_non_null =
856 TimestampMicrosecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
857 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
858
859 assert_eq!(vortex_array.len(), 4);
860 assert_eq!(vortex_array_non_null.len(), 4);
861 }
862
863 #[test]
864 fn test_timestamp_timezone_microsecond_array_conversion() {
865 let arrow_array =
866 TimestampMicrosecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)])
867 .with_timezone("UTC");
868 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
869
870 let arrow_array_non_null =
871 TimestampMicrosecondArray::from(vec![1000_i64, 2000, 3000, 4000]).with_timezone("UTC");
872 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
873
874 assert_eq!(vortex_array.len(), 4);
875 assert_eq!(
876 vortex_array.dtype(),
877 &DType::Extension(Arc::new(ExtDType::new(
878 TIMESTAMP_ID.clone(),
879 Arc::new(DType::Primitive(PType::I64, Nullability::Nullable)),
880 Some(
881 TemporalMetadata::Timestamp(TimeUnit::Microseconds, Some("UTC".to_string()))
882 .into()
883 )
884 )))
885 );
886 assert_eq!(vortex_array_non_null.len(), 4);
887 assert_eq!(
888 vortex_array_non_null.dtype(),
889 &DType::Extension(Arc::new(ExtDType::new(
890 TIMESTAMP_ID.clone(),
891 Arc::new(DType::Primitive(PType::I64, Nullability::NonNullable)),
892 Some(
893 TemporalMetadata::Timestamp(TimeUnit::Microseconds, Some("UTC".to_string()))
894 .into()
895 )
896 )))
897 );
898 }
899
900 #[test]
901 fn test_timestamp_nanosecond_array_conversion() {
902 let arrow_array =
903 TimestampNanosecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
904 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
905
906 let arrow_array_non_null = TimestampNanosecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
907 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
908
909 assert_eq!(vortex_array.len(), 4);
910 assert_eq!(vortex_array_non_null.len(), 4);
911 }
912
913 #[test]
914 fn test_time32_second_array_conversion() {
915 let arrow_array = Time32SecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
916 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
917
918 let arrow_array_non_null = Time32SecondArray::from(vec![1000_i32, 2000, 3000, 4000]);
919 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
920
921 assert_eq!(vortex_array.len(), 4);
922 assert_eq!(vortex_array_non_null.len(), 4);
923
924 let temporal_array = TemporalArray::try_from(vortex_array.clone()).unwrap();
926 assert_eq!(
927 temporal_array.temporal_metadata().time_unit(),
928 TimeUnit::Seconds
929 );
930
931 let temporal_array_non_null =
932 TemporalArray::try_from(vortex_array_non_null.clone()).unwrap();
933 assert_eq!(
934 temporal_array_non_null.temporal_metadata().time_unit(),
935 TimeUnit::Seconds
936 );
937 }
938
939 #[test]
940 fn test_time32_millisecond_array_conversion() {
941 let arrow_array =
942 Time32MillisecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
943 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
944
945 let arrow_array_non_null = Time32MillisecondArray::from(vec![1000_i32, 2000, 3000, 4000]);
946 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
947
948 assert_eq!(vortex_array.len(), 4);
949 assert_eq!(vortex_array_non_null.len(), 4);
950 }
951
952 #[test]
953 fn test_time64_microsecond_array_conversion() {
954 let arrow_array =
955 Time64MicrosecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
956 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
957
958 let arrow_array_non_null = Time64MicrosecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
959 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
960
961 assert_eq!(vortex_array.len(), 4);
962 assert_eq!(vortex_array_non_null.len(), 4);
963 }
964
965 #[test]
966 fn test_time64_nanosecond_array_conversion() {
967 let arrow_array =
968 Time64NanosecondArray::from(vec![Some(1000), None, Some(3000), Some(4000)]);
969 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
970
971 let arrow_array_non_null = Time64NanosecondArray::from(vec![1000_i64, 2000, 3000, 4000]);
972 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
973
974 assert_eq!(vortex_array.len(), 4);
975 assert_eq!(vortex_array_non_null.len(), 4);
976 }
977
978 #[test]
979 fn test_date32_array_conversion() {
980 let arrow_array = Date32Array::from(vec![Some(18000), None, Some(18002), Some(18003)]);
981 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
982
983 let arrow_array_non_null = Date32Array::from(vec![18000_i32, 18001, 18002, 18003]);
984 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
985
986 assert_eq!(vortex_array.len(), 4);
987 assert_eq!(vortex_array_non_null.len(), 4);
988 }
989
990 #[test]
991 fn test_date64_array_conversion() {
992 let arrow_array = Date64Array::from(vec![
993 Some(1555200000000),
994 None,
995 Some(1555286400000),
996 Some(1555372800000),
997 ]);
998 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
999
1000 let arrow_array_non_null = Date64Array::from(vec![
1001 1555200000000_i64,
1002 1555213600000,
1003 1555286400000,
1004 1555372800000,
1005 ]);
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]
1014 fn test_utf8_array_conversion() {
1015 let arrow_array = StringArray::from(vec![Some("hello"), None, Some("world"), Some("test")]);
1016 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1017
1018 let arrow_array_non_null = StringArray::from(vec!["hello", "world", "test", "vortex"]);
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 let varbin_array = vortex_array.as_::<VarBinVTable>();
1026 assert_eq!(varbin_array.dtype(), &DType::Utf8(true.into()));
1027
1028 let varbin_array_non_null = vortex_array_non_null.as_::<VarBinVTable>();
1029 assert_eq!(varbin_array_non_null.dtype(), &DType::Utf8(false.into()));
1030 }
1031
1032 #[test]
1033 fn test_large_utf8_array_conversion() {
1034 let arrow_array =
1035 LargeStringArray::from(vec![Some("hello"), None, Some("world"), Some("test")]);
1036 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1037
1038 let arrow_array_non_null = LargeStringArray::from(vec!["hello", "world", "test", "vortex"]);
1039 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1040
1041 assert_eq!(vortex_array.len(), 4);
1042 assert_eq!(vortex_array_non_null.len(), 4);
1043 }
1044
1045 #[test]
1046 fn test_binary_array_conversion() {
1047 let arrow_array = BinaryArray::from(vec![
1048 Some("hello".as_bytes()),
1049 None,
1050 Some("world".as_bytes()),
1051 Some("test".as_bytes()),
1052 ]);
1053 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1054
1055 let arrow_array_non_null = BinaryArray::from(vec![
1056 "hello".as_bytes(),
1057 "world".as_bytes(),
1058 "test".as_bytes(),
1059 "vortex".as_bytes(),
1060 ]);
1061 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1062
1063 assert_eq!(vortex_array.len(), 4);
1064 assert_eq!(vortex_array_non_null.len(), 4);
1065 }
1066
1067 #[test]
1068 fn test_large_binary_array_conversion() {
1069 let arrow_array = LargeBinaryArray::from(vec![
1070 Some("hello".as_bytes()),
1071 None,
1072 Some("world".as_bytes()),
1073 Some("test".as_bytes()),
1074 ]);
1075 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1076
1077 let arrow_array_non_null = LargeBinaryArray::from(vec![
1078 "hello".as_bytes(),
1079 "world".as_bytes(),
1080 "test".as_bytes(),
1081 "vortex".as_bytes(),
1082 ]);
1083 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1084
1085 assert_eq!(vortex_array.len(), 4);
1086 assert_eq!(vortex_array_non_null.len(), 4);
1087 }
1088
1089 #[test]
1090 fn test_utf8_view_array_conversion() {
1091 let mut builder = StringViewBuilder::new();
1092 builder.append_value("hello");
1093 builder.append_null();
1094 builder.append_value("world");
1095 builder.append_value("test");
1096 let arrow_array = builder.finish();
1097 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1098
1099 let mut builder_non_null = StringViewBuilder::new();
1100 builder_non_null.append_value("hello");
1101 builder_non_null.append_value("world");
1102 builder_non_null.append_value("test");
1103 builder_non_null.append_value("vortex");
1104 let arrow_array_non_null = builder_non_null.finish();
1105 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1106
1107 assert_eq!(vortex_array.len(), 4);
1108 assert_eq!(vortex_array_non_null.len(), 4);
1109
1110 let varbin_view_array = vortex_array.as_::<VarBinViewVTable>();
1112 assert_eq!(
1113 varbin_view_array.buffers().len(),
1114 arrow_array.data_buffers().len()
1115 );
1116 assert_eq!(varbin_view_array.dtype(), &DType::Utf8(true.into()));
1117
1118 let varbin_view_array_non_null = vortex_array_non_null.as_::<VarBinViewVTable>();
1119 assert_eq!(
1120 varbin_view_array_non_null.buffers().len(),
1121 arrow_array_non_null.data_buffers().len()
1122 );
1123 assert_eq!(
1124 varbin_view_array_non_null.dtype(),
1125 &DType::Utf8(false.into())
1126 );
1127 }
1128
1129 #[test]
1130 fn test_binary_view_array_conversion() {
1131 let mut builder = BinaryViewBuilder::new();
1132 builder.append_value(b"hello");
1133 builder.append_null();
1134 builder.append_value(b"world");
1135 builder.append_value(b"test");
1136 let arrow_array = builder.finish();
1137 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1138
1139 let mut builder_non_null = BinaryViewBuilder::new();
1140 builder_non_null.append_value(b"hello");
1141 builder_non_null.append_value(b"world");
1142 builder_non_null.append_value(b"test");
1143 builder_non_null.append_value(b"vortex");
1144 let arrow_array_non_null = builder_non_null.finish();
1145 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1146
1147 assert_eq!(vortex_array.len(), 4);
1148 assert_eq!(vortex_array_non_null.len(), 4);
1149
1150 let varbin_view_array = vortex_array.as_::<VarBinViewVTable>();
1152 assert_eq!(
1153 varbin_view_array.buffers().len(),
1154 arrow_array.data_buffers().len()
1155 );
1156 assert_eq!(varbin_view_array.dtype(), &DType::Binary(true.into()));
1157
1158 let varbin_view_array_non_null = vortex_array_non_null.as_::<VarBinViewVTable>();
1159 assert_eq!(
1160 varbin_view_array_non_null.buffers().len(),
1161 arrow_array_non_null.data_buffers().len()
1162 );
1163 assert_eq!(
1164 varbin_view_array_non_null.dtype(),
1165 &DType::Binary(false.into())
1166 );
1167 }
1168
1169 #[test]
1171 fn test_boolean_array_conversion() {
1172 let arrow_array = BooleanArray::from(vec![Some(true), None, Some(false), Some(true)]);
1173 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1174
1175 let arrow_array_non_null = BooleanArray::from(vec![true, false, true, false]);
1176 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1177
1178 assert_eq!(vortex_array.len(), 4);
1179 assert_eq!(vortex_array_non_null.len(), 4);
1180 }
1181
1182 #[test]
1184 fn test_struct_array_conversion() {
1185 let fields = vec![
1186 Field::new("field1", DataType::Int32, true),
1187 Field::new("field2", DataType::Utf8, false),
1188 ];
1189 let schema = Fields::from(fields);
1190
1191 let field1_data = Int32Array::from(vec![Some(1), None, Some(3)]);
1192 let field2_data = StringArray::from(vec!["a", "b", "c"]);
1193
1194 let arrow_array = StructArray::new(
1195 schema.clone(),
1196 vec![Arc::new(field1_data), Arc::new(field2_data)],
1197 None,
1198 );
1199
1200 let vortex_array = ArrayRef::from_arrow(&arrow_array, false);
1201 assert_eq!(vortex_array.len(), 3);
1202
1203 let struct_vortex_array = vortex_array.as_::<StructVTable>();
1205 assert_eq!(struct_vortex_array.names().len(), 2);
1206 assert_eq!(struct_vortex_array.names()[0], "field1");
1207 assert_eq!(struct_vortex_array.names()[1], "field2");
1208
1209 let nullable_array = StructArray::new(
1211 schema,
1212 vec![
1213 Arc::new(Int32Array::from(vec![Some(1), None, Some(3)])),
1214 Arc::new(StringArray::from(vec!["a", "b", "c"])),
1215 ],
1216 Some(arrow_buffer::NullBuffer::new(BooleanBuffer::from(vec![
1217 true, false, true,
1218 ]))),
1219 );
1220
1221 let vortex_nullable_array = ArrayRef::from_arrow(&nullable_array, true);
1222 assert_eq!(vortex_nullable_array.len(), 3);
1223
1224 let struct_vortex_nullable_array = vortex_nullable_array.as_::<StructVTable>();
1226 assert_eq!(struct_vortex_nullable_array.names().len(), 2);
1227 assert_eq!(struct_vortex_nullable_array.names()[0], "field1");
1228 assert_eq!(struct_vortex_nullable_array.names()[1], "field2");
1229 }
1230
1231 #[test]
1233 fn test_list_array_conversion() {
1234 let mut builder = ListBuilder::new(Int32Builder::new());
1235 builder.append_value([Some(1), None, Some(3)]);
1236 builder.append_null();
1237 builder.append_value([Some(4), Some(5)]);
1238 let arrow_array = builder.finish();
1239
1240 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1241 assert_eq!(vortex_array.len(), 3);
1242
1243 let list_vortex_array = vortex_array.as_::<ListVTable>();
1245 let offsets_array = list_vortex_array.offsets().as_::<PrimitiveVTable>();
1246 assert_eq!(offsets_array.len(), 4); assert_eq!(offsets_array.ptype(), PType::I32);
1248
1249 let mut builder_non_null = ListBuilder::new(Int32Builder::new());
1251 builder_non_null.append_value([Some(1), None, Some(3)]);
1252 builder_non_null.append_value([Some(4), Some(5)]);
1253 let arrow_array_non_null = builder_non_null.finish();
1254
1255 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1256 assert_eq!(vortex_array_non_null.len(), 2);
1257
1258 let list_vortex_array_non_null = vortex_array_non_null.as_::<ListVTable>();
1260 let offsets_array_non_null = list_vortex_array_non_null
1261 .offsets()
1262 .as_::<PrimitiveVTable>();
1263 assert_eq!(offsets_array_non_null.len(), 3); assert_eq!(offsets_array_non_null.ptype(), PType::I32);
1265 }
1266
1267 #[test]
1268 fn test_large_list_array_conversion() {
1269 let mut builder = LargeListBuilder::new(Int32Builder::new());
1270 builder.append_value([Some(1), None, Some(3)]);
1271 builder.append_null();
1272 builder.append_value([Some(4), Some(5)]);
1273 let arrow_array = builder.finish();
1274
1275 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1276 assert_eq!(vortex_array.len(), 3);
1277
1278 let list_vortex_array = vortex_array.as_::<ListVTable>();
1280 let offsets_array = list_vortex_array.offsets().as_::<PrimitiveVTable>();
1281 assert_eq!(offsets_array.len(), 4); assert_eq!(offsets_array.ptype(), PType::I64); let mut builder_non_null = LargeListBuilder::new(Int32Builder::new());
1286 builder_non_null.append_value([Some(1), None, Some(3)]);
1287 builder_non_null.append_value([Some(4), Some(5)]);
1288 let arrow_array_non_null = builder_non_null.finish();
1289
1290 let vortex_array_non_null = ArrayRef::from_arrow(&arrow_array_non_null, false);
1291 assert_eq!(vortex_array_non_null.len(), 2);
1292
1293 let list_vortex_array_non_null = vortex_array_non_null.as_::<ListVTable>();
1295 let offsets_array_non_null = list_vortex_array_non_null
1296 .offsets()
1297 .as_::<PrimitiveVTable>();
1298 assert_eq!(offsets_array_non_null.len(), 3); assert_eq!(offsets_array_non_null.ptype(), PType::I64); }
1301
1302 #[test]
1304 fn test_null_array_conversion() {
1305 let arrow_array = NullArray::new(5);
1306 let vortex_array = ArrayRef::from_arrow(&arrow_array, true);
1307 assert_eq!(vortex_array.len(), 5);
1308 }
1309
1310 #[test]
1312 fn test_arrow_buffer_conversion() {
1313 let data = vec![1u8, 2, 3, 4, 5];
1314 let arrow_buffer = ArrowBuffer::from_vec(data);
1315 let vortex_array = arrow_buffer.into_array();
1316 assert_eq!(vortex_array.len(), 5);
1317 }
1318
1319 #[test]
1320 fn test_boolean_buffer_conversion() {
1321 let data = vec![true, false, true, false, true];
1322 let boolean_buffer = BooleanBuffer::from(data);
1323 let vortex_array = boolean_buffer.into_array();
1324 assert_eq!(vortex_array.len(), 5);
1325 }
1326
1327 #[test]
1328 fn test_scalar_buffer_conversion() {
1329 let data = vec![1i32, 2, 3, 4, 5];
1330 let scalar_buffer = ScalarBuffer::from(data);
1331 let vortex_array = scalar_buffer.into_array();
1332 assert_eq!(vortex_array.len(), 5);
1333 }
1334
1335 #[test]
1336 fn test_offset_buffer_conversion() {
1337 let data = vec![0i32, 2, 5, 8, 10];
1338 let offset_buffer = OffsetBuffer::new(ScalarBuffer::from(data));
1339 let vortex_array = offset_buffer.into_array();
1340 assert_eq!(vortex_array.len(), 5);
1341 }
1342
1343 #[test]
1345 fn test_record_batch_conversion() {
1346 let schema = Arc::new(Schema::new(vec![
1347 Field::new("field1", DataType::Int32, false),
1348 Field::new("field2", DataType::Utf8, false),
1349 ]));
1350
1351 let field1_data = Arc::new(Int32Array::from(vec![1, 2, 3, 4]));
1352 let field2_data = Arc::new(StringArray::from(vec!["a", "b", "c", "d"]));
1353
1354 let record_batch = RecordBatch::try_new(schema, vec![field1_data, field2_data]).unwrap();
1355
1356 let vortex_array = ArrayRef::from_arrow(record_batch, false);
1357 assert_eq!(vortex_array.len(), 4);
1358
1359 let schema = Arc::new(Schema::new(vec![
1361 Field::new("field1", DataType::Int32, false),
1362 Field::new("field2", DataType::Utf8, false),
1363 ]));
1364
1365 let field1_data = Arc::new(Int32Array::from(vec![1, 2, 3, 4]));
1366 let field2_data = Arc::new(StringArray::from(vec!["a", "b", "c", "d"]));
1367
1368 let record_batch = RecordBatch::try_new(schema, vec![field1_data, field2_data]).unwrap();
1369
1370 let vortex_array = ArrayRef::from_arrow(&record_batch, false);
1371 assert_eq!(vortex_array.len(), 4);
1372 }
1373
1374 #[test]
1376 fn test_dyn_array_conversion() {
1377 let int_array = Int32Array::from(vec![1, 2, 3, 4]);
1378 let dyn_array: &dyn ArrowArray = &int_array;
1379 let vortex_array = ArrayRef::from_arrow(dyn_array, false);
1380 assert_eq!(vortex_array.len(), 4);
1381
1382 let string_array = StringArray::from(vec!["a", "b", "c"]);
1383 let dyn_array: &dyn ArrowArray = &string_array;
1384 let vortex_array = ArrayRef::from_arrow(dyn_array, false);
1385 assert_eq!(vortex_array.len(), 3);
1386
1387 let bool_array = BooleanArray::from(vec![true, false, true]);
1388 let dyn_array: &dyn ArrowArray = &bool_array;
1389 let vortex_array = ArrayRef::from_arrow(dyn_array, false);
1390 assert_eq!(vortex_array.len(), 3);
1391 }
1392
1393 #[test]
1395 pub fn nullable_may_contain_non_nullable() {
1396 let null_struct_array_with_non_nullable_field = new_null_array(
1397 &DataType::Struct(Fields::from(vec![Field::new(
1398 "non_nullable_inner",
1399 DataType::Int32,
1400 false,
1401 )])),
1402 1,
1403 );
1404 ArrayRef::from_arrow(null_struct_array_with_non_nullable_field.as_ref(), true);
1405 }
1406
1407 #[test]
1408 pub fn nullable_may_contain_deeply_nested_non_nullable() {
1409 let null_struct_array_with_non_nullable_field = new_null_array(
1410 &DataType::Struct(Fields::from(vec![Field::new(
1411 "non_nullable_inner",
1412 DataType::Struct(Fields::from(vec![Field::new(
1413 "non_nullable_deeper_inner",
1414 DataType::Int32,
1415 false,
1416 )])),
1417 false,
1418 )])),
1419 1,
1420 );
1421 ArrayRef::from_arrow(null_struct_array_with_non_nullable_field.as_ref(), true);
1422 }
1423
1424 #[test]
1425 #[should_panic]
1426 pub fn cannot_handle_nullable_struct_containing_non_nullable_dictionary() {
1427 let null_struct_array_with_non_nullable_field = new_null_array(
1428 &DataType::Struct(Fields::from(vec![Field::new(
1429 "non_nullable_deeper_inner",
1430 DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8)),
1431 false,
1432 )])),
1433 1,
1434 );
1435
1436 ArrayRef::from_arrow(null_struct_array_with_non_nullable_field.as_ref(), true);
1437 }
1438}