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 6f3376398f Fix union slice logical_nulls length (#7855)
6f3376398f is described below

commit 6f3376398f536af1b21d625e3b70e82dfa1b6fba
Author: Yan Tingwang <[email protected]>
AuthorDate: Tue Jul 8 20:57:02 2025 +0800

    Fix union slice logical_nulls length (#7855)
    
    # Which issue does this PR close?
    
    - Closes #7647.
    
    # Rationale for this change
    
    Fixes the incorrect length of logical_nulls for sliced single-field
    dense union arrays.
    
    # What changes are included in this PR?
    
    N/A
    
    # Are these changes tested?
    
    add test  slice_union_array_single_field();
    
    # Are there any user-facing changes?
    
    N/A
    
    ---------
    
    Signed-off-by: root <[email protected]>
    Signed-off-by: codephage2020 <[email protected]>
    Co-authored-by: root <[email protected]>
---
 arrow-array/src/array/union_array.rs | 43 ++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/arrow-array/src/array/union_array.rs 
b/arrow-array/src/array/union_array.rs
index 061bd71a77..1350cae3a3 100644
--- a/arrow-array/src/array/union_array.rs
+++ b/arrow-array/src/array/union_array.rs
@@ -781,13 +781,18 @@ impl Array for UnionArray {
         };
 
         if fields.len() <= 1 {
-            return self
-                .fields
-                .iter()
-                .flatten()
-                .map(Array::logical_nulls)
-                .next()
-                .flatten();
+            return self.fields.iter().find_map(|field_opt| {
+                field_opt
+                    .as_ref()
+                    .and_then(|field| field.logical_nulls())
+                    .map(|logical_nulls| {
+                        if self.is_dense() {
+                            self.gather_nulls(vec![(0, logical_nulls)]).into()
+                        } else {
+                            logical_nulls
+                        }
+                    })
+            });
         }
 
         let logical_nulls = self.fields_logical_nulls();
@@ -1074,6 +1079,30 @@ mod tests {
         }
     }
 
+    #[test]
+    fn slice_union_array_single_field() {
+        // Dense Union
+        // [1, null, 3, null, 4]
+        let union_array = {
+            let mut builder = UnionBuilder::new_dense();
+            builder.append::<Int32Type>("a", 1).unwrap();
+            builder.append_null::<Int32Type>("a").unwrap();
+            builder.append::<Int32Type>("a", 3).unwrap();
+            builder.append_null::<Int32Type>("a").unwrap();
+            builder.append::<Int32Type>("a", 4).unwrap();
+            builder.build().unwrap()
+        };
+
+        // [null, 3, null]
+        let union_slice = union_array.slice(1, 3);
+        let logical_nulls = union_slice.logical_nulls().unwrap();
+
+        assert_eq!(logical_nulls.len(), 3);
+        assert!(logical_nulls.is_null(0));
+        assert!(logical_nulls.is_valid(1));
+        assert!(logical_nulls.is_null(2));
+    }
+
     #[test]
     #[cfg_attr(miri, ignore)]
     fn test_dense_i32_large() {

Reply via email to