From c5d058993925194436b994de4b883ca267f3f063 Mon Sep 17 00:00:00 2001 From: waterWang Date: Fri, 28 Aug 2026 10:58:08 +0800 Subject: [PATCH] GH-51018: [C++] Fix indices_nonzero segfault on chunkless ChunkedArray Calling indices_nonzero on a ChunkedArray with zero chunks (e.g. the shape produced by filtering a table down to no rows) segfaulted. IndicesNonZeroExecChunked built an empty vector of ArraySpans, and DoNonZero unconditionally dereferenced arrays[0].type, performing an out-of-bounds vector access. Guard DoNonZero so an empty chunk vector yields an empty result, consistent with the zero-length Array and single-empty-chunk cases. --- cpp/src/arrow/compute/kernels/vector_selection.cc | 6 ++++-- cpp/src/arrow/compute/kernels/vector_selection_test.cc | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cpp/src/arrow/compute/kernels/vector_selection.cc b/cpp/src/arrow/compute/kernels/vector_selection.cc index 6f8dd52a4fd2..687e0d933923 100644 --- a/cpp/src/arrow/compute/kernels/vector_selection.cc +++ b/cpp/src/arrow/compute/kernels/vector_selection.cc @@ -264,8 +264,10 @@ Status DoNonZero(const std::vector& arrays, int64_t total_length, UInt64Builder builder; RETURN_NOT_OK(builder.Reserve(total_length)); - NonZeroVisitor visitor(&builder, arrays); - RETURN_NOT_OK(VisitTypeInline(*arrays[0].type, &visitor)); + if (!arrays.empty()) { + NonZeroVisitor visitor(&builder, arrays); + RETURN_NOT_OK(VisitTypeInline(*arrays[0].type, &visitor)); + } return builder.FinishInternal(out); } diff --git a/cpp/src/arrow/compute/kernels/vector_selection_test.cc b/cpp/src/arrow/compute/kernels/vector_selection_test.cc index c79720985399..5e38ac15306f 100644 --- a/cpp/src/arrow/compute/kernels/vector_selection_test.cc +++ b/cpp/src/arrow/compute/kernels/vector_selection_test.cc @@ -2920,6 +2920,14 @@ TEST(TestIndicesNonZero, IndicesNonZero) { actual, CallFunction("indices_nonzero", {static_cast(chunked_arr_empty)})); AssertArraysEqual(*ArrayFromJSON(uint64(), "[0, 2, 3, 5]"), *actual.make_array(), /*verbose*/ true); + + // chunked with zero chunks (GH-51018) + ChunkedArray chunked_arr_no_chunks({}, type); + ASSERT_OK_AND_ASSIGN( + actual, + CallFunction("indices_nonzero", {static_cast(chunked_arr_no_chunks)})); + AssertArraysEqual(*ArrayFromJSON(uint64(), "[]"), *actual.make_array(), + /*verbose*/ true); } }