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