Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions cpp/src/arrow/compute/kernels/scalar_cast_string.cc
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,14 @@ BinaryToBinaryCastExec(KernelContext* ctx, const ExecSpan& batch, ExecResult* ou
OffsetBuilder offset_builder(ctx->memory_pool());
RETURN_NOT_OK(offset_builder.Reserve(input.length + 1));
offset_builder.UnsafeAppend(0); // offsets start at 0
const int64_t sum_of_binary_view_sizes = util::SumOfBinaryViewSizes(
input.GetValues<BinaryViewType::c_type>(1), input.length);
// Null views are undefined and may hold any size, so only sum the valid ones
const auto* views = input.GetValues<BinaryViewType::c_type>(1);
int64_t sum_of_binary_view_sizes = 0;
arrow::internal::VisitSetBitRunsVoid(
input.buffers[0].data, input.offset, input.length,
[&](int64_t position, int64_t length) {
sum_of_binary_view_sizes += util::SumOfBinaryViewSizes(views + position, length);
});
DataBuilder data_builder(ctx->memory_pool());
RETURN_NOT_OK(data_builder.Reserve(sum_of_binary_view_sizes));
VisitArraySpanInline<I>(
Expand Down
20 changes: 20 additions & 0 deletions cpp/src/arrow/compute/kernels/scalar_cast_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3450,6 +3450,26 @@ TEST(Cast, StringToString) {
}
}

TEST(Cast, BinaryViewToBinaryNullViewSize) {
// Views under a null bit are undefined and may hold a negative size; it must
// not shrink the output data buffer.
auto json = R"(["foofoofoofoofoo", null, "barbarbarbarbarbarbar"])";
for (auto from_type : {utf8_view(), binary_view()}) {
auto data = ArrayFromJSON(from_type, json)->data()->Copy();
ASSERT_OK_AND_ASSIGN(data->buffers[1],
data->buffers[1]->CopySlice(0, data->buffers[1]->size()));
data->GetMutableValues<BinaryViewType::c_type>(1)[1].inlined.size = -36;
auto from = MakeArray(data);
ASSERT_OK(from->ValidateFull());

for (auto to_type : {utf8(), large_utf8(), binary(), large_binary()}) {
ASSERT_OK_AND_ASSIGN(auto out, Cast(*from, to_type));
ValidateOutput(*out);
AssertArraysEqual(*ArrayFromJSON(to_type, json), *out, /*verbose=*/true);
}
}
}

TEST(Cast, StringToStringWithOffset) {
// GH-43660: Check casting String Arrays with nonzero offset
std::vector<int64_t> offsets = {3, 8, 10, 12};
Expand Down
Loading