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 fea605cb16 [Variant] Fix cast logic for Variant to Arrow for 
DataType::Null (#8825)
fea605cb16 is described below

commit fea605cb16f7524cb69a197bfa581a1d4f5fe5d0
Author: Congxian Qiu <[email protected]>
AuthorDate: Thu Nov 20 02:17:12 2025 +0800

    [Variant] Fix cast logic for Variant to Arrow for DataType::Null (#8825)
    
    # Which issue does this PR close?
    
    - Closes #8810 .
    
    
    # What changes are included in this PR?
    
    Fix the logic for `VariantToNullArrowRowBuilder` so that it respects the
    `cast` option
    
    # Are these changes tested?
    
    added test
    
    # Are there any user-facing changes?
    
    Noe
---
 parquet-variant-compute/src/variant_get.rs      | 38 +++++++++++++++++++++++++
 parquet-variant-compute/src/variant_to_arrow.rs | 21 ++++++++------
 2 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/parquet-variant-compute/src/variant_get.rs 
b/parquet-variant-compute/src/variant_get.rs
index b082035ac0..82f02c3df8 100644
--- a/parquet-variant-compute/src/variant_get.rs
+++ b/parquet-variant-compute/src/variant_get.rs
@@ -319,6 +319,7 @@ mod test {
     use arrow::compute::CastOptions;
     use arrow::datatypes::DataType::{Int16, Int32, Int64};
     use arrow::datatypes::i256;
+    use arrow::util::display::FormatOptions;
     use arrow_schema::DataType::{Boolean, Float32, Float64, Int8};
     use arrow_schema::{DataType, Field, FieldRef, Fields, IntervalUnit, 
TimeUnit};
     use chrono::DateTime;
@@ -1039,6 +1040,43 @@ mod test {
         arrow::array::NullArray::new(3)
     );
 
+    
perfectly_shredded_variant_array_fn!(perfectly_shredded_null_variant_array_with_int,
 || {
+        Int32Array::from(vec![Some(32), Some(64), Some(48)])
+    });
+
+    // We append null values if type miss match happens in safe mode
+    perfectly_shredded_to_arrow_primitive_test!(
+        get_variant_perfectly_shredded_null_with_type_missmatch_in_safe_mode,
+        DataType::Null,
+        perfectly_shredded_null_variant_array_with_int,
+        arrow::array::NullArray::new(3)
+    );
+
+    // We'll return an error if type miss match happens in strict mode
+    #[test]
+    fn 
get_variant_perfectly_shredded_null_as_null_with_type_missmatch_in_strict_mode()
 {
+        let array = perfectly_shredded_null_variant_array_with_int();
+        let field = Field::new("typed_value", DataType::Null, true);
+        let options = GetOptions::new()
+            .with_as_type(Some(FieldRef::from(field)))
+            .with_cast_options(CastOptions {
+                safe: false,
+                format_options: FormatOptions::default(),
+            });
+
+        let result = variant_get(&array, options);
+
+        assert!(result.is_err());
+        let error_msg = format!("{}", result.unwrap_err());
+        assert!(
+            error_msg
+                .contains("Cast error: Failed to extract primitive of type 
Null from variant Int32(32) at path VariantPath([])"),
+            "Expected=[Cast error: Failed to extract primitive of type Null 
from variant Int32(32) at path VariantPath([])],\
+                Got error message=[{}]",
+            error_msg
+        );
+    }
+
     
perfectly_shredded_variant_array_fn!(perfectly_shredded_decimal4_variant_array, 
|| {
         Decimal32Array::from(vec![Some(12345), Some(23400), Some(-12342)])
             .with_precision_and_scale(5, 2)
diff --git a/parquet-variant-compute/src/variant_to_arrow.rs 
b/parquet-variant-compute/src/variant_to_arrow.rs
index 6b0e05dd26..9d158dd96d 100644
--- a/parquet-variant-compute/src/variant_to_arrow.rs
+++ b/parquet-variant-compute/src/variant_to_arrow.rs
@@ -696,24 +696,29 @@ impl VariantToBinaryVariantArrowRowBuilder {
     }
 }
 
-struct FakeNullBuilder(NullArray);
+#[derive(Default)]
+struct FakeNullBuilder {
+    item_count: usize,
+}
 
 impl FakeNullBuilder {
-    fn new(capacity: usize) -> Self {
-        Self(NullArray::new(capacity))
+    fn append_value(&mut self, _: ()) {
+        self.item_count += 1;
+    }
+
+    fn append_null(&mut self) {
+        self.item_count += 1;
     }
-    fn append_value<T>(&mut self, _: T) {}
-    fn append_null(&mut self) {}
 
     fn finish(self) -> NullArray {
-        self.0
+        NullArray::new(self.item_count)
     }
 }
 
 define_variant_to_primitive_builder!(
     struct VariantToNullArrowRowBuilder<'a>
-    |capacity| -> FakeNullBuilder { FakeNullBuilder::new(capacity) },
-    |_value|  Some(Variant::Null),
+    |_capacity| -> FakeNullBuilder { FakeNullBuilder::default() },
+    |value| value.as_null(),
     type_name: "Null"
 );
 

Reply via email to