diff --git a/cpp/src/arrow/compute/row/encode_internal.cc b/cpp/src/arrow/compute/row/encode_internal.cc index 0e2720a2866..0d57cb83bfd 100644 --- a/cpp/src/arrow/compute/row/encode_internal.cc +++ b/cpp/src/arrow/compute/row/encode_internal.cc @@ -279,7 +279,7 @@ void EncoderInteger::Decode(uint32_t start_row, uint32_t num_rows, case 4: for (uint32_t i = 0; i < num_rows; ++i) { reinterpret_cast(col_base)[i] = *reinterpret_cast( - rows.fixed_length_rows(start_row + i + offset_within_row)); + rows.fixed_length_rows(start_row + i) + offset_within_row); } break; case 8: diff --git a/cpp/src/arrow/compute/row/grouper_test.cc b/cpp/src/arrow/compute/row/grouper_test.cc index 0b8d8da0a6b..3ed2fde2e94 100644 --- a/cpp/src/arrow/compute/row/grouper_test.cc +++ b/cpp/src/arrow/compute/row/grouper_test.cc @@ -825,6 +825,28 @@ TEST(Grouper, DictKey) { g.grouper_->Consume(dict_span)); } +// GH-45393: Test combinations of numeric type keys of different lengths. +TEST(Grouper, MultipleIntKeys) { + auto types = NumericTypes(); + for (auto& t0 : types) { + ARROW_SCOPED_TRACE("t0=", t0->ToString()); + for (auto& t1 : types) { + ARROW_SCOPED_TRACE("t1=", t1->ToString()); + for (auto& t2 : types) { + ARROW_SCOPED_TRACE("t2=", t2->ToString()); + TestGrouper g({t0, t1, t2}); + + g.ExpectConsume(R"([[0, 1, 2], [0, 1, 2]])", "[0, 0]"); + g.ExpectConsume(R"([[0, 1, 2], [null, 1, 2]])", "[0, 1]"); + g.ExpectConsume(R"([[0, 1, 2], [0, null, 2]])", "[0, 2]"); + g.ExpectConsume(R"([[0, 1, 2], [0, 1, null]])", "[0, 3]"); + + g.ExpectUniques("[[0, 1, 2], [null, 1, 2], [0, null, 2], [0, 1, null]]"); + } + } + } +} + TEST(Grouper, StringInt64Key) { TestGrouper g({utf8(), int64()});