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() {

Reply via email to