diff --git a/arrow/src/array/equal/list.rs b/arrow/src/array/equal/list.rs index 65d320c0079d..0feefa7aa11a 100644 --- a/arrow/src/array/equal/list.rs +++ b/arrow/src/array/equal/list.rs @@ -73,6 +73,11 @@ pub(super) fn list_equal( // however, one is more likely to slice into a list array and get a region that has 0 // child values. // The test that triggered this behaviour had [4, 4] as a slice of 1 value slot. + // For the edge case that zero length list arrays are always equal. + if len == 0 { + return true; + } + let lhs_child_length = lhs_offsets[lhs_start + len].to_usize().unwrap() - lhs_offsets[lhs_start].to_usize().unwrap(); diff --git a/arrow/src/array/equal/mod.rs b/arrow/src/array/equal/mod.rs index b89a8fa53e0b..c3b0bbc95c2b 100644 --- a/arrow/src/array/equal/mod.rs +++ b/arrow/src/array/equal/mod.rs @@ -629,6 +629,57 @@ mod tests { test_equal(&a, &b, false); } + #[test] + fn test_empty_offsets_list_equal() { + let empty: Vec = vec![]; + let values = Int32Array::from(empty); + let empty_offsets: [u8; 0] = []; + + let a = ArrayDataBuilder::new(DataType::List(Box::new(Field::new( + "item", + DataType::Int32, + true, + )))) + .len(0) + .add_buffer(Buffer::from(&empty_offsets)) + .add_child_data(values.data().clone()) + .null_bit_buffer(Some(Buffer::from(&empty_offsets))) + .build() + .unwrap(); + + let b = ArrayDataBuilder::new(DataType::List(Box::new(Field::new( + "item", + DataType::Int32, + true, + )))) + .len(0) + .add_buffer(Buffer::from(&empty_offsets)) + .add_child_data(values.data().clone()) + .null_bit_buffer(Some(Buffer::from(&empty_offsets))) + .build() + .unwrap(); + + test_equal(&a, &b, true); + + let c = ArrayDataBuilder::new(DataType::List(Box::new(Field::new( + "item", + DataType::Int32, + true, + )))) + .len(0) + .add_buffer(Buffer::from(vec![0i32, 2, 3, 4, 6, 7, 8].to_byte_slice())) + .add_child_data( + Int32Array::from(vec![1, 2, -1, -2, 3, 4, -3, -4]) + .data() + .clone(), + ) + .null_bit_buffer(Some(Buffer::from(vec![0b00001001]))) + .build() + .unwrap(); + + test_equal(&a, &c, true); + } + // Test the case where null_count > 0 #[test] fn test_list_null() {