This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 498e41aa22 fix(variant): improve malformed object field diagnostics
(#10638)
498e41aa22 is described below
commit 498e41aa227acf331ea2079333554df2c4275d01
Author: cakeni <[email protected]>
AuthorDate: Thu Aug 20 06:13:19 2026 +0800
fix(variant): improve malformed object field diagnostics (#10638)
# Which issue does this PR close?
- Closes #10619.
# Rationale for this change
A named child of a shredded object is required to use the shredded
Variant field Struct layout. Treating a present child with another Arrow
type as a missing path would hide malformed input, so the existing
InvalidArgumentError is the correct boundary.
# What changes are included in this PR?
- Document the shredded-object field invariant where it is validated.
- Include the field name and actual Arrow type in the error.
- Add a malformed Int32 child regression test.
# Are these changes tested?
- cargo +stable-x86_64-pc-windows-gnu test -p parquet-variant-compute
--lib (348 passed)
- cargo fmt --all -- --check
- git diff --check
# Are there any user-facing changes?
Malformed shredded object errors now identify the offending field and
physical type. There are no public API changes.
## AI assistance
OpenAI Codex assisted with investigating the error path and drafting the
fix and regression tests. I reviewed and verified the final change.
Co-authored-by: Jeffrey Vo <[email protected]>
---
parquet-variant-compute/src/variant_get.rs | 35 ++++++++++++++++++++++++++----
1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/parquet-variant-compute/src/variant_get.rs
b/parquet-variant-compute/src/variant_get.rs
index 92eda7b864..ccaa9d5b75 100644
--- a/parquet-variant-compute/src/variant_get.rs
+++ b/parquet-variant-compute/src/variant_get.rs
@@ -145,11 +145,11 @@ pub(crate) fn follow_shredded_path_element(
};
let struct_array = field.as_struct_opt().ok_or_else(|| {
- // TODO: Should we blow up? Or just end the traversal and let
the normal
- // variant pathing code sort out the mess that it must anyway
be
- // prepared to handle?
+ // Each named child of a shredded object represents a shredded
Variant field,
+ // whose physical layout is a Struct containing `value` and/or
`typed_value`.
ArrowError::InvalidArgumentError(format!(
- "Expected Struct array while following path, got {}",
+ "Shredded object field '{name}' must be a Struct
containing 'value' and/or \
+ 'typed_value', got {}",
field.data_type(),
))
})?;
@@ -1919,6 +1919,33 @@ mod test {
assert_eq!(result_variant.value(1), Variant::Int32(42));
}
+ #[test]
+ fn test_malformed_shredded_object_field_reports_field_and_type() {
+ let metadata =
+
BinaryViewArray::from_iter_values(std::iter::repeat_n(EMPTY_VARIANT_METADATA_BYTES,
2));
+ let typed_value = StructArray::try_new(
+ Fields::from(vec![Field::new("x", DataType::Int32, true)]),
+ vec![Arc::new(Int32Array::from(vec![Some(1), Some(42)]))],
+ None,
+ )
+ .unwrap();
+ let array = ArrayRef::from(VariantArray::from_parts(
+ Arc::new(metadata),
+ all_null_value_column(2),
+ Some(Arc::new(typed_value)),
+ None,
+ ));
+
+ let options =
GetOptions::new_with_path(VariantPath::try_from("x").unwrap());
+ let err = variant_get(&array, options).unwrap_err();
+
+ assert_eq!(
+ err.to_string(),
+ "Invalid argument error: Shredded object field 'x' must be a
Struct containing \
+ 'value' and/or 'typed_value', got Int32"
+ );
+ }
+
/// Test extracting shredded object field with type conversion
#[test]
fn test_shredded_object_field_as_int32() {