Skip to content

Commit

Permalink
fix: panic when casting ListArray to FixedSizeList (#5643)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahgao committed Apr 15, 2024
1 parent 883c13a commit fee6921
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
6 changes: 4 additions & 2 deletions arrow-cast/src/cast/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ where
{
let cap = array.len() * size as usize;

let mut nulls = (cast_options.safe || array.null_count() != 0).then(|| {
// Whether the resulting array may contain null lists
let nullable = cast_options.safe || array.null_count() != 0;
let mut nulls = nullable.then(|| {
let mut buffer = BooleanBufferBuilder::new(array.len());
match array.nulls() {
Some(n) => buffer.append_buffer(n.inner()),
Expand All @@ -74,7 +76,7 @@ where

// Nulls in FixedSizeListArray take up space and so we must pad the values
let values = array.values().to_data();
let mut mutable = MutableArrayData::new(vec![&values], cast_options.safe, cap);
let mut mutable = MutableArrayData::new(vec![&values], nullable, cap);
// The end position in values of the last incorrectly-sized list slice
let mut last_pos = 0;
for (idx, w) in array.offsets().windows(2).enumerate() {
Expand Down
21 changes: 21 additions & 0 deletions arrow-cast/src/cast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6806,6 +6806,27 @@ mod tests {
3,
)) as ArrayRef;
assert_eq!(expected.as_ref(), res.as_ref());

// The safe option is false and the source array contains a null list.
// issue: https://github.com/apache/arrow-rs/issues/5642
let array = Arc::new(ListArray::from_iter_primitive::<Int32Type, _, _>(vec![
Some(vec![Some(1), Some(2), Some(3)]),
None,
])) as ArrayRef;
let res = cast_with_options(
array.as_ref(),
&DataType::FixedSizeList(Arc::new(Field::new("item", DataType::Int32, true)), 3),
&CastOptions {
safe: false,
..Default::default()
},
)
.unwrap();
let expected = Arc::new(FixedSizeListArray::from_iter_primitive::<Int32Type, _, _>(
vec![Some(vec![Some(1), Some(2), Some(3)]), None],
3,
)) as ArrayRef;
assert_eq!(expected.as_ref(), res.as_ref());
}

#[test]
Expand Down

0 comments on commit fee6921

Please sign in to comment.