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