This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch 59_maintenance
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/59_maintenance by this push:
new 1bbe4caa82 [59_maintenance] fix(arrow-data): fix gaps in ListView
equality (#11439)
1bbe4caa82 is described below
commit 1bbe4caa826f026809f3a4ca441371a31cd23a0c
Author: Jeffrey Vo <[email protected]>
AuthorDate: Fri Oct 9 02:52:35 2026 +0900
[59_maintenance] fix(arrow-data): fix gaps in ListView equality (#11439)
- Backport https://github.com/apache/arrow-rs/pull/11345
- For inclusion in https://github.com/apache/arrow-rs/issues/11352
Cherry-pick of
https://github.com/apache/arrow-rs/commit/862b1e065b602400784268df9ded5d0a18710eed
---------
Co-authored-by: Neil Conway <[email protected]>
---
Cargo.lock | 9 +++++----
arrow-data/src/equal/list_view.rs | 23 +++++++++++++++--------
arrow-data/src/equal/mod.rs | 3 +++
arrow/tests/array_equal.rs | 26 ++++++++++++++++++++++++++
4 files changed, 49 insertions(+), 12 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index f70f848d43..65f3d138c7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -604,9 +604,9 @@ checksum =
"c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "aws-lc-rs"
-version = "1.16.3"
+version = "1.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f"
+checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e"
dependencies = [
"aws-lc-sys",
"zeroize",
@@ -614,14 +614,15 @@ dependencies = [
[[package]]
name = "aws-lc-sys"
-version = "0.40.0"
+version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7"
+checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27"
dependencies = [
"cc",
"cmake",
"dunce",
"fs_extra",
+ "pkg-config",
]
[[package]]
diff --git a/arrow-data/src/equal/list_view.rs
b/arrow-data/src/equal/list_view.rs
index c7cb31db90..299414b135 100644
--- a/arrow-data/src/equal/list_view.rs
+++ b/arrow-data/src/equal/list_view.rs
@@ -17,7 +17,7 @@
use crate::ArrayData;
use crate::data::count_nulls;
-use crate::equal::equal_values;
+use crate::equal::equal_range;
use arrow_buffer::ArrowNativeType;
use num_integer::Integer;
@@ -74,8 +74,7 @@ pub(super) fn list_view_equal<T: ArrowNativeType + Integer>(
let rhs_offset = rhs_offset.to_usize().unwrap();
let size = size.to_usize().unwrap();
- // Check if offsets are valid for the given range
- if !equal_values(lhs_data, rhs_data, lhs_offset, rhs_offset, size)
{
+ if !equal_range(lhs_data, rhs_data, lhs_offset, rhs_offset, size) {
return false;
}
}
@@ -101,10 +100,10 @@ pub(super) fn list_view_equal<T: ArrowNativeType +
Integer>(
return false;
}
- for (index, ((&lhs_offset, &rhs_offset), &size)) in lhs_range_offsets
+ for (index, ((&lhs_offset, &rhs_offset), (&lhs_size, &rhs_size))) in
lhs_range_offsets
.iter()
.zip(rhs_range_offsets)
- .zip(lhs_range_sizes)
+ .zip(lhs_range_sizes.iter().zip(rhs_range_sizes))
.enumerate()
{
let lhs_is_null = lhs_nulls.is_null(index);
@@ -114,12 +113,20 @@ pub(super) fn list_view_equal<T: ArrowNativeType +
Integer>(
return false;
}
+ // Null rows are equal whatever their sizes and values
+ if lhs_is_null {
+ continue;
+ }
+
+ if lhs_size != rhs_size {
+ return false;
+ }
+
let lhs_offset = lhs_offset.to_usize().unwrap();
let rhs_offset = rhs_offset.to_usize().unwrap();
- let size = size.to_usize().unwrap();
+ let size = lhs_size.to_usize().unwrap();
- // Check if values match in the range
- if !lhs_is_null && !equal_values(lhs_data, rhs_data, lhs_offset,
rhs_offset, size) {
+ if !equal_range(lhs_data, rhs_data, lhs_offset, rhs_offset, size) {
return false;
}
}
diff --git a/arrow-data/src/equal/mod.rs b/arrow-data/src/equal/mod.rs
index b241b8cf66..011f591d10 100644
--- a/arrow-data/src/equal/mod.rs
+++ b/arrow-data/src/equal/mod.rs
@@ -58,6 +58,9 @@ use variable_size::variable_sized_equal;
/// Compares the values of two [ArrayData] starting at `lhs_start` and
`rhs_start` respectively
/// for `len` slots.
+///
+/// Assumes the null masks of the two ranges are already known to be equal. To
compare
+/// ranges of child data, use [`equal_range`], which also compares the null
masks.
#[inline]
fn equal_values(
lhs: &ArrayData,
diff --git a/arrow/tests/array_equal.rs b/arrow/tests/array_equal.rs
index 381054a25d..c21096c6dc 100644
--- a/arrow/tests/array_equal.rs
+++ b/arrow/tests/array_equal.rs
@@ -822,6 +822,22 @@ fn test_test_list_view_array<T: OffsetSizeTrait>() {
test_equal(&a, &b, true);
}
+fn test_list_view_sizes_and_child_nulls<T: OffsetSizeTrait>() {
+ // Same first elements but different sizes, with a null row
+ let a = create_list_view_array::<T, _, _>([Some(vec![Some(1), Some(2)]),
None]);
+ let b = create_list_view_array::<T, _, _>([Some(vec![Some(1), Some(2),
Some(3)]), None]);
+ test_equal(&a, &b, false);
+
+ // Child values that differ only in their null masks, without and with a
null row
+ let a = create_list_view_array::<T, _, _>([Some(vec![Some(1), Some(0)])]);
+ let b = create_list_view_array::<T, _, _>([Some(vec![Some(1), None])]);
+ test_equal(&a, &b, false);
+
+ let a = create_list_view_array::<T, _, _>([None, Some(vec![Some(1),
Some(0)])]);
+ let b = create_list_view_array::<T, _, _>([None, Some(vec![Some(1),
None])]);
+ test_equal(&a, &b, false);
+}
+
// Special test for List<ListView<i32>>.
// This tests the equal_ranges kernel
fn test_sliced_list_of_list_view<T: OffsetSizeTrait>() {
@@ -871,6 +887,16 @@ fn test_large_list_view_array() {
test_test_list_view_array::<i64>();
}
+#[test]
+fn test_list_view_array_sizes_and_child_nulls() {
+ test_list_view_sizes_and_child_nulls::<i32>();
+}
+
+#[test]
+fn test_large_list_view_array_sizes_and_child_nulls() {
+ test_list_view_sizes_and_child_nulls::<i64>();
+}
+
#[test]
fn test_nested_list_view_array() {
test_sliced_list_of_list_view::<i32>();