This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-11355-1d1607a761e1dff1a104aefcf6ff248f2579818c
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git

commit 170d51ba2d416c06abab67f906a2cd8a30753bc8
Author: Neil Conway <[email protected]>
AuthorDate: Sat Oct 3 14:27:13 2026 +0000

    fix(arrow-cast): avoid panicking during failed List -> ListView cast 
(#11355)
    
    # Which issue does this PR close?
    
    - N/A
    
    # Rationale for this change
    
    `cast_list_to_list_view` built its result with
    `GenericListViewArray::new`, which panics if the ListViewArray would be
    invalid. This meant that casting to a `ListView` with a non-nullable
    field panicked if the input contained a null element, rather than
    returning an error.
    
    # What changes are included in this PR?
    
    * Use `try_new` instead of `new`, matching other casts
    * Add unit test
    
    # Are these changes tested?
    
    Yes; existing tests pass, new test added.
    
    # Are there any significant user-facing changes?
    
    No.
    
    # AI usage
    
    Developed with Claude Code (Opus 5.5). I have reviewed and understand
    the resulting code.
---
 arrow-cast/src/cast/list.rs |  4 ++--
 arrow-cast/src/cast/mod.rs  | 22 ++++++++++++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/arrow-cast/src/cast/list.rs b/arrow-cast/src/cast/list.rs
index ee35b1a9f3..6eac84c4dd 100644
--- a/arrow-cast/src/cast/list.rs
+++ b/arrow-cast/src/cast/list.rs
@@ -480,12 +480,12 @@ pub(crate) fn cast_list_to_list_view<I: OffsetSizeTrait, 
O: OffsetSizeTrait>(
         sizes.push(O::usize_as(size));
     }
     let values = cast_with_options(&values, to_field.data_type(), 
cast_options)?;
-    let array = GenericListViewArray::<O>::new(
+    let array = GenericListViewArray::<O>::try_new(
         to_field.clone(),
         view_offsets.into(),
         sizes.into(),
         values,
         nulls,
-    );
+    )?;
     Ok(Arc::new(array))
 }
diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs
index 0887345d05..6cf6fcc5cd 100644
--- a/arrow-cast/src/cast/mod.rs
+++ b/arrow-cast/src/cast/mod.rs
@@ -14305,6 +14305,28 @@ mod tests {
         assert_eq!(got_list_view, &expected_list_view);
     }
 
+    #[test]
+    fn test_cast_list_to_list_view_null_in_non_nullable_field() {
+        // i32::MAX does not fit in Int16, so a safe cast turns it into a null
+        let list = ListArray::from_iter_primitive::<Int32Type, _, 
_>([Some(vec![
+            Some(1),
+            Some(i32::MAX),
+        ])]);
+        let field = Arc::new(Field::new_list_field(DataType::Int16, false));
+        for (target_type, array_name) in [
+            (DataType::ListView(field.clone()), "ListViewArray"),
+            (DataType::LargeListView(field), "LargeListViewArray"),
+        ] {
+            let err = cast(&list, &target_type).unwrap_err();
+            assert_eq!(
+                err.to_string(),
+                format!(
+                    "Invalid argument error: Non-nullable field of 
{array_name} \"item\" cannot contain nulls"
+                )
+            );
+        }
+    }
+
     #[test]
     fn test_cast_large_list_view_to_large_list() {
         let list_view =

Reply via email to