Skip to content

Commit 7e625a7

Browse files
authored
fix[vortex-array]: don't use input list field type in preferred conversion (#4481)
This would cause a panic in arrow when attempting to create a list when the preferred conversion resulted in a different element array type due to the different types. This commit also simplifies the input arguments so that preferred type conversion never has access to the canonical arrow type. Ran into this while testing #4464 Signed-off-by: Alfonso Subiotto Marques <[email protected]>
1 parent 2e2eecf commit 7e625a7

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

vortex-array/src/arrow/compute/to_arrow/canonical.rs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,10 @@ impl Kernel for ToArrowCanonical {
142142
to_arrow_struct(array, fields.as_ref(), arrow_type_opt.is_none())
143143
}
144144
(Canonical::List(array), DataType::List(field)) => {
145-
to_arrow_list::<i32>(array, field, arrow_type_opt.is_none())
145+
to_arrow_list::<i32>(array, arrow_type_opt.map(|_| field))
146146
}
147147
(Canonical::List(array), DataType::LargeList(field)) => {
148-
to_arrow_list::<i64>(array, field, arrow_type_opt.is_none())
148+
to_arrow_list::<i64>(array, arrow_type_opt.map(|_| field))
149149
}
150150
(Canonical::FixedSizeList(..), DataType::FixedSizeList(..)) => {
151151
unimplemented!("TODO(connor)[FixedSizeList]")
@@ -355,24 +355,31 @@ fn to_arrow_struct(
355355

356356
fn to_arrow_list<O: NativePType + OffsetSizeTrait>(
357357
array: ListArray,
358-
element: &FieldRef,
359-
to_preferred: bool,
358+
element: Option<&FieldRef>,
360359
) -> VortexResult<ArrowArrayRef> {
361360
// First we cast the offsets into the correct width.
362361
let offsets_dtype = DType::Primitive(O::PTYPE, array.dtype().nullability());
363362
let arrow_offsets = cast(array.offsets(), &offsets_dtype)
364363
.map_err(|err| err.with_context(format!("Failed to cast offsets to {offsets_dtype}")))?
365364
.to_primitive();
366365

367-
let values = if to_preferred {
368-
array.elements().clone().into_arrow_preferred()?
366+
let (values, element_field) = if let Some(element) = element {
367+
(
368+
array.elements().clone().into_arrow(element.data_type())?,
369+
element.clone(),
370+
)
369371
} else {
370-
array.elements().clone().into_arrow(element.data_type())?
372+
let values = array.elements().clone().into_arrow_preferred()?;
373+
let element_field = Arc::new(Field::new_list_field(
374+
values.data_type().clone(),
375+
array.elements().dtype().is_nullable(),
376+
));
377+
(values, element_field)
371378
};
372379
let nulls = array.validity_mask().to_null_buffer();
373380

374381
Ok(Arc::new(GenericListArray::new(
375-
element.clone(),
382+
element_field,
376383
arrow_offsets.buffer::<O>().into_arrow_offset_buffer(),
377384
values,
378385
nulls,
@@ -423,7 +430,7 @@ mod tests {
423430
use vortex_scalar::NativeDecimalType;
424431

425432
use crate::IntoArray;
426-
use crate::arrays::{DecimalArray, PrimitiveArray, StructArray};
433+
use crate::arrays::{DecimalArray, ListArray, PrimitiveArray, StructArray};
427434
use crate::arrow::IntoArrowArray;
428435
use crate::arrow::compute::to_arrow;
429436
use crate::builders::{ArrayBuilder, DecimalBuilder};
@@ -557,4 +564,18 @@ mod tests {
557564
assert_eq!(arrow_decimal.value(1), i256::from_i128(11));
558565
assert_eq!(arrow_decimal.value(2), i256::from_i128(12));
559566
}
567+
568+
#[test]
569+
fn to_arrow_list_preferred() {
570+
let elements = PrimitiveArray::new(buffer![1u8, 2, 3, 4, 5], Validity::NonNullable);
571+
let offsets = PrimitiveArray::new(buffer![0i32, 3, 5], Validity::NonNullable);
572+
let list_array = ListArray::try_new(
573+
elements.into_array(),
574+
offsets.into_array(),
575+
Validity::AllValid,
576+
)
577+
.unwrap();
578+
579+
list_array.into_array().into_arrow_preferred().unwrap();
580+
}
560581
}

0 commit comments

Comments
 (0)