This is an automated email from the ASF dual-hosted git repository.

scovich 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 58fbb17285 remove panics in unshred variant (#9741)
58fbb17285 is described below

commit 58fbb172854f7d8949227226a0c746239d15d52a
Author: Matthew Kim <[email protected]>
AuthorDate: Thu Apr 16 11:50:57 2026 -0400

    remove panics in unshred variant (#9741)
    
    - Closes https://github.com/apache/arrow-rs/issues/9740
---
 parquet-variant-compute/src/unshred_variant.rs | 29 ++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/parquet-variant-compute/src/unshred_variant.rs 
b/parquet-variant-compute/src/unshred_variant.rs
index ecffd48bc4..7bf31e2256 100644
--- a/parquet-variant-compute/src/unshred_variant.rs
+++ b/parquet-variant-compute/src/unshred_variant.rs
@@ -81,7 +81,7 @@ pub fn unshred_variant(array: &VariantArray) -> 
Result<VariantArray> {
                     "metadata field must be a binary-like array".to_string(),
                 )
             })?;
-            let metadata = VariantMetadata::new(metadata_bytes);
+            let metadata = VariantMetadata::try_new(metadata_bytes)?;
             let mut value_builder = value_builder.builder_ext(&metadata);
             row_builder.append_row(&mut value_builder, &metadata, i)?;
         }
@@ -338,7 +338,7 @@ impl<'a> ValueOnlyUnshredVariantBuilder<'a> {
                     "value field must be a binary-like array".to_string(),
                 )
             })?;
-            let variant = Variant::new_with_metadata(metadata.clone(), 
value_bytes);
+            let variant = Variant::try_new_with_metadata(metadata.clone(), 
value_bytes)?;
             builder.append_value(variant);
         }
         Ok(())
@@ -368,7 +368,7 @@ macro_rules! handle_unshredded_case {
                         v.data_type(),
                     ))
                 })?;
-                Result::Ok(Variant::new_with_metadata($metadata.clone(), 
bytes))
+                Variant::try_new_with_metadata($metadata.clone(), bytes)
             })
             .transpose()?;
 
@@ -628,7 +628,8 @@ impl<'a> StructUnshredVariantBuilder<'a> {
                 ));
             };
 
-            for (field_name, field_value) in object.iter() {
+            for entry in object.iter_try() {
+                let (field_name, field_value) = entry?;
                 if self.field_unshredders.contains_key(field_name) {
                     return Err(ArrowError::InvalidArgumentError(format!(
                         "Field '{field_name}' appears in both typed_value and 
value",
@@ -795,4 +796,24 @@ mod tests {
         assert_eq!(result.value(1), Variant::from(&b"\xff\xaa"[..]));
         assert_eq!(result.value(2), Variant::from(&b"\xde\xad\xbe\xef"[..]));
     }
+
+    #[test]
+    fn test_unshred_returns_err_on_malformed_metadata() {
+        // empty metadata bytes fail VariantMetadata's header parse. before 
this fix the
+        // call inside unshred_variant used the panicking 
`VariantMetadata::new`, which
+        // crashed the thread instead of surfacing the spec violation through 
the
+        // documented `Result` return type.
+        let metadata: ArrayRef = 
Arc::new(BinaryViewArray::from_iter_values(vec![&b""[..]]));
+
+        let typed_value: ArrayRef = 
Arc::new(StringViewArray::from(vec![Some("hello")]));
+
+        let variant_array = VariantArray::from_parts(metadata, None, 
Some(typed_value), None);
+
+        let result = crate::unshred_variant(&variant_array);
+
+        assert!(
+            result.is_err(),
+            "unshred_variant must return Err on malformed metadata, not panic",
+        );
+    }
 }

Reply via email to