This is an automated email from the ASF dual-hosted git repository.
pitrou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new a2a9dce9d8f GH-50524: [C++] Honor array offset in pairwise_diff
(#50858)
a2a9dce9d8f is described below
commit a2a9dce9d8fbcb822fbb54a52efc2f52d1bb6516
Author: Krishnanand G <[email protected]>
AuthorDate: Tue Aug 25 19:16:17 2026 +0530
GH-50524: [C++] Honor array offset in pairwise_diff (#50858)
### Rationale for this change
`ArraySpan::SetSlice` replaces the offset. `pairwise_diff` copied the input
span and then sliced from `left_start`/`right_start`, so a sliced array was
read from the parent buffer. With `[99, 1, 4, 9, 16]` sliced to `[1, 4, 9,
16]`, period=1 produced `[-98, 3, 5, 7]` instead of `[null, 3, 5, 7]`.
### What changes are included in this PR?
The kernel passes `input.offset + left_start` (and the same for the right
side). The regression test uses a sliced int64 array for both period signs, on
`pairwise_diff` and `pairwise_diff_checked`.
### Are these changes tested?
Yes, `TestPairwiseDiff.SlicedInput` in `vector_pairwise_test.cc`.
### Are there any user-facing changes?
`pairwise_diff` on a sliced array now diffs the sliced values. Callers who
passed a slice and got parent-buffer values will see different (correct) output.
* GitHub Issue: #50524
Authored-by: Krishnanand G
<[email protected]>
Signed-off-by: Antoine Pitrou <[email protected]>
---
cpp/src/arrow/compute/kernels/vector_pairwise.cc | 6 ++++--
.../arrow/compute/kernels/vector_pairwise_test.cc | 20 ++++++++++++++++++++
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/cpp/src/arrow/compute/kernels/vector_pairwise.cc
b/cpp/src/arrow/compute/kernels/vector_pairwise.cc
index 51d6f959acf..55dedeef849 100644
--- a/cpp/src/arrow/compute/kernels/vector_pairwise.cc
+++ b/cpp/src/arrow/compute/kernels/vector_pairwise.cc
@@ -73,10 +73,12 @@ Status PairwiseExecImpl(KernelContext* ctx, const
ArraySpan& input,
}
result->null_count = null_count;
// prepare input span
+ // SetSlice overwrites offset. Keep the input's offset so a sliced
+ // array is not read from the start of the parent buffer.
ArraySpan left(input);
- left.SetSlice(left_start, computed_length);
+ left.SetSlice(input.offset + left_start, computed_length);
ArraySpan right(input);
- right.SetSlice(right_start, computed_length);
+ right.SetSlice(input.offset + right_start, computed_length);
// prepare output span
ArraySpan output_span;
output_span.SetMembers(*result);
diff --git a/cpp/src/arrow/compute/kernels/vector_pairwise_test.cc
b/cpp/src/arrow/compute/kernels/vector_pairwise_test.cc
index cae9469c3c9..7a13f5b5341 100644
--- a/cpp/src/arrow/compute/kernels/vector_pairwise_test.cc
+++ b/cpp/src/arrow/compute/kernels/vector_pairwise_test.cc
@@ -151,6 +151,26 @@ TEST_F(TestPairwiseDiff, Numeric) {
}
}
+TEST_F(TestPairwiseDiff, SlicedInput) {
+ // Slice() keeps a nonzero offset into the parent buffer. The kernel
+ // used to treat that offset as zero and read values before the slice.
+ auto base = ArrayFromJSON(int64(), "[99, 1, 4, 9, 16, 88]");
+ auto sliced = base->Slice(1, 4);
+
+ {
+ PairwiseOptions options(1);
+ auto expected = ArrayFromJSON(int64(), "[null, 3, 5, 7]");
+ CheckVectorUnary("pairwise_diff", sliced, expected, &options);
+ CheckVectorUnary("pairwise_diff_checked", sliced, expected, &options);
+ }
+ {
+ PairwiseOptions options(-1);
+ auto expected = ArrayFromJSON(int64(), "[-3, -5, -7, null]");
+ CheckVectorUnary("pairwise_diff", sliced, expected, &options);
+ CheckVectorUnary("pairwise_diff_checked", sliced, expected, &options);
+ }
+}
+
TEST_F(TestPairwiseDiff, Overflow) {
{
PairwiseOptions options(1);