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)) } }
