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-11356-2741db581b707b18515034b7adf2f2f24efe303e
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git

commit b94434d8c0880243fdd80c813a7ee6eb4a29ce72
Author: Neil Conway <[email protected]>
AuthorDate: Mon Oct 5 01:30:45 2026 +0000

    fix(variant): avoid panic on `variant_get` for non-nullable field (#11356)
    
    # Which issue does this PR close?
    
    - N/A
    
    # Rationale for this change
    
    `variant_get` built `List` and `ListView` results using
    `GenericListArray::new` and `GenericListViewArray::new`, which panic if
    the array would be invalid. Given a list type with a non-nullable field,
    asking for a result with a null value in such a field would panic
    instead of returning an error.
    
    # What changes are included in this PR?
    
    * Use `try_new` instead of `new`, matching the existing FSL and struct
    paths
    * Add unit test
    
    # Are these changes tested?
    
    Yes; existing test 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.
---
 parquet-variant-compute/src/variant_get.rs      | 30 +++++++++++++++++++++++++
 parquet-variant-compute/src/variant_to_arrow.rs |  8 +++----
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/parquet-variant-compute/src/variant_get.rs 
b/parquet-variant-compute/src/variant_get.rs
index 96d634d516..97cc3b00d9 100644
--- a/parquet-variant-compute/src/variant_get.rs
+++ b/parquet-variant-compute/src/variant_get.rs
@@ -5013,6 +5013,36 @@ mod test {
         assert_eq!(values.value(2), 3);
     }
 
+    #[test]
+    fn test_variant_get_list_like_null_element_in_non_nullable_item() {
+        let item_field = Arc::new(Field::new("item", Int64, false));
+        let data_types = [
+            (DataType::List(item_field.clone()), "ListArray"),
+            (DataType::LargeList(item_field.clone()), "LargeListArray"),
+            (DataType::ListView(item_field.clone()), "ListViewArray"),
+            (DataType::LargeListView(item_field), "LargeListViewArray"),
+        ];
+        // A null element, and an element that a safe cast turns into null
+        for json in ["[1, null, 3]", r#"[1, "two", 3]"#] {
+            let string_array: ArrayRef = 
Arc::new(StringArray::from(vec![json]));
+            let variant_array = 
ArrayRef::from(json_to_variant(&string_array).unwrap());
+            for (data_type, array_name) in &data_types {
+                let options = 
GetOptions::new().with_as_type(Some(FieldRef::from(Field::new(
+                    "result",
+                    data_type.clone(),
+                    true,
+                ))));
+                let err = variant_get(&variant_array, options).unwrap_err();
+                assert_eq!(
+                    err.to_string(),
+                    format!(
+                        "Invalid argument error: Non-nullable field of 
{array_name} \"item\" cannot contain nulls"
+                    )
+                );
+            }
+        }
+    }
+
     #[test]
     fn test_variant_get_list_like_unsafe_cast_errors_on_non_list() {
         let string_array: ArrayRef = Arc::new(StringArray::from(vec!["[1, 2]", 
"\"not a list\""]));
diff --git a/parquet-variant-compute/src/variant_to_arrow.rs 
b/parquet-variant-compute/src/variant_to_arrow.rs
index 7febecaab5..033856acc0 100644
--- a/parquet-variant-compute/src/variant_to_arrow.rs
+++ b/parquet-variant-compute/src/variant_to_arrow.rs
@@ -1575,21 +1575,21 @@ where
                 sizes.push(self.offsets[i] - self.offsets[i - 1]);
             }
             self.offsets.pop();
-            let list_view_array = GenericListViewArray::<O>::new(
+            let list_view_array = GenericListViewArray::<O>::try_new(
                 field,
                 ScalarBuffer::from(self.offsets),
                 ScalarBuffer::from(sizes),
                 element_array,
                 self.nulls.finish(),
-            );
+            )?;
             Ok(Arc::new(list_view_array))
         } else {
-            let list_array = GenericListArray::<O>::new(
+            let list_array = GenericListArray::<O>::try_new(
                 field,
                 OffsetBuffer::<O>::new(ScalarBuffer::from(self.offsets)),
                 element_array,
                 self.nulls.finish(),
-            );
+            )?;
             Ok(Arc::new(list_array))
         }
     }

Reply via email to