You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by gi...@apache.org on 2026/10/05 01:39:02 UTC
(arrow-rs) 01/01: fix(variant): avoid panic on `variant_get` for non-nullable field (#11356)
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 <ne...@gmail.com>
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))
}
}