From e45a92748f0a46142d2b5a936eb56c4d74d6c884 Mon Sep 17 00:00:00 2001 From: Rossi Sun Date: Thu, 26 Mar 2026 14:28:07 -0700 Subject: [PATCH 1/2] GH-49392: [C++][Compute] Fix fixed-width gather byte offset overflow --- cpp/src/arrow/compute/kernels/gather_internal.h | 14 ++++++++++---- .../arrow/compute/kernels/vector_selection_test.cc | 13 +++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/cpp/src/arrow/compute/kernels/gather_internal.h b/cpp/src/arrow/compute/kernels/gather_internal.h index 4c161533a727..de3872bf7c3f 100644 --- a/cpp/src/arrow/compute/kernels/gather_internal.h +++ b/cpp/src/arrow/compute/kernels/gather_internal.h @@ -35,6 +35,11 @@ namespace arrow::internal { +template +constexpr int64_t FixedWidthByteOffset(IndexType index, int64_t value_width) { + return static_cast(index) * value_width; +} + // CRTP [1] base class for Gather that provides a gathering loop in terms of // Write*() methods that must be implemented by the derived class. // @@ -185,8 +190,8 @@ class Gather : public GatherBaseCRTP::max() / kByteWidth + 1; + constexpr int64_t kExpectedByteOffset = + static_cast(std::numeric_limits::max()) + 1; + + const int64_t byte_offset = ::arrow::internal::FixedWidthByteOffset(kIndex, kByteWidth); + ASSERT_EQ(byte_offset, kExpectedByteOffset); + ASSERT_GT(byte_offset, std::numeric_limits::max()); +} + // ---------------------------------------------------------------------- TEST(GetTakeIndices, Basics) { From c2ab6771adb403233a6e59bbd0dc54a5cbf6c816 Mon Sep 17 00:00:00 2001 From: Rossi Sun Date: Mon, 30 Mar 2026 11:27:54 -0700 Subject: [PATCH 2/2] GH-49392: Remove helper-level gather test --- .../arrow/compute/kernels/vector_selection_test.cc | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/cpp/src/arrow/compute/kernels/vector_selection_test.cc b/cpp/src/arrow/compute/kernels/vector_selection_test.cc index edac6e431da9..5fa2d6824dc1 100644 --- a/cpp/src/arrow/compute/kernels/vector_selection_test.cc +++ b/cpp/src/arrow/compute/kernels/vector_selection_test.cc @@ -27,7 +27,6 @@ #include "arrow/array/concatenate.h" #include "arrow/chunked_array.h" #include "arrow/compute/api.h" -#include "arrow/compute/kernels/gather_internal.h" #include "arrow/compute/kernels/test_util_internal.h" #include "arrow/scalar.h" #include "arrow/table.h" @@ -105,18 +104,6 @@ void CheckTakeIndicesCase(const std::string& filter_json, const std::string& ind } // namespace -// GH-49392: Fixed-width gather byte offsets must be computed in int64_t. -TEST(GatherInternal, FixedWidthByteOffsetUses64BitArithmetic) { - constexpr int64_t kByteWidth = 8; - constexpr uint32_t kIndex = std::numeric_limits::max() / kByteWidth + 1; - constexpr int64_t kExpectedByteOffset = - static_cast(std::numeric_limits::max()) + 1; - - const int64_t byte_offset = ::arrow::internal::FixedWidthByteOffset(kIndex, kByteWidth); - ASSERT_EQ(byte_offset, kExpectedByteOffset); - ASSERT_GT(byte_offset, std::numeric_limits::max()); -} - // ---------------------------------------------------------------------- TEST(GetTakeIndices, Basics) {