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 3b61796582 fix: first next_back() on new RowsIter panics (#9505)
3b61796582 is described below
commit 3b6179658203dc1b1610b67c1777d5b8beb137fc
Author: Raz Luvaton <[email protected]>
AuthorDate: Wed Mar 18 16:27:12 2026 +0200
fix: first next_back() on new RowsIter panics (#9505)
# Which issue does this PR close?
N/A
# Rationale for this change
it should not panic
# What changes are included in this PR?
correctly use last row in `next_back`
# Are these changes tested?
yes
# Are there any user-facing changes?
they can now use `next_back`
---
arrow-row/src/lib.rs | 43 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 41 insertions(+), 2 deletions(-)
diff --git a/arrow-row/src/lib.rs b/arrow-row/src/lib.rs
index 9679c89b48..078c457477 100644
--- a/arrow-row/src/lib.rs
+++ b/arrow-row/src/lib.rs
@@ -1414,9 +1414,12 @@ impl DoubleEndedIterator for RowsIter<'_> {
if self.end == self.start {
return None;
}
- // Safety: We have checked that `start` is less than `end`
- let row = unsafe { self.rows.row_unchecked(self.end) };
+
self.end -= 1;
+
+ // Safety: By construction we create `end >= start`, so if `end` is
not equal to `start` it cannot be less than `start`
+ // therefore `end - 1` is within range
+ let row = unsafe { self.rows.row_unchecked(self.end) };
Some(row)
}
}
@@ -5651,4 +5654,40 @@ mod tests {
.contains("not yet implemented")
);
}
+
+ #[test]
+ fn empty_row_iter_next_back() {
+ let rows = RowConverter::new(vec![SortField::new(DataType::UInt8)])
+ .unwrap()
+ .empty_rows(0, 0);
+ let mut rows_iter = rows.iter();
+ assert_eq!(rows_iter.next_back(), None);
+ assert_eq!(rows_iter.next_back(), None);
+ assert_eq!(rows_iter.next_back(), None);
+ }
+
+ #[test]
+ fn row_iter_next_back() {
+ let row_converter =
RowConverter::new(vec![SortField::new(DataType::UInt8)]).unwrap();
+ let mut rng = StdRng::seed_from_u64(42);
+ let array = generate_primitive_array::<UInt8Type>(&mut rng, 100, 0.8);
+ let rows = row_converter.convert_columns(&[Arc::new(array)]).unwrap();
+
+ let mut rows_iter = rows.iter();
+ let mut bytes: Vec<u8> = vec![];
+
+ while let Some(row) = rows_iter.next_back() {
+ bytes.extend(row.data.iter().rev());
+ }
+
+ bytes.reverse();
+
+ assert_eq!(
+ bytes,
+ &rows.buffer.as_slice()[..*rows.offsets.last().unwrap()]
+ );
+
+ assert_eq!(rows_iter.next_back(), None);
+ assert_eq!(rows_iter.next(), None);
+ }
}