Repository navigation
[C++][Compute] Conditional compute kernels (if_else, coalesce, case_when, choose) do not support string_view or binary_view #55255
Description
Describe the bug, including details regarding any error messages, version, and platform.
The conditional compute kernels (if_else, coalesce, case_when, and choose) fail with arrow::Status::NotImplemented when passed utf8_view (string_view) or binary_view arrays or scalars.
While classic variable-length binary types (utf8, large_utf8, binary, large_binary) have full support across all conditional compute kernels, modern string/binary-view types are missing kernel registrations and fail type dispatch.
In cpp/src/arrow/compute/kernels/scalar_if_else.cc, the registration helpers only iterate over BaseBinaryTypes():
// if_else
AddBinaryIfElseKernels(func, BaseBinaryTypes());
// case_when
for (const auto& ty : BaseBinaryTypes()) {
AddCaseWhenKernel(func, ty, GenerateTypeAgnosticVarBinaryBase<CaseWhenFunctor>(ty));
}
// coalesce
for (const auto& ty : BaseBinaryTypes()) {
AddCoalesceKernel(func, ty, GenerateTypeAgnosticVarBinaryBase<CoalesceFunctor>(ty));
}
// choose
for (const auto& ty : BaseBinaryTypes()) {
AddChooseKernel(func, ty, GenerateTypeAgnosticVarBinaryBase<ChooseFunctor>(ty));
}BaseBinaryTypes() includes only utf8, large_utf8, binary, and large_binary. Neither StringViewType nor BinaryViewType is registered.
Furthermore, in cpp/src/arrow/compute/kernels/codegen_internal.cc, CommonBinary does not resolve view types and returns TypeHolder(nullptr).
Reproduction
The failure reproduces in C++ (and PyArrow):
TEST(TestIfElseKernel, StringViewSupport) {
auto view_type = utf8_view();
auto cond = ArrayFromJSON(boolean(), "[true, false, true]");
auto left = ArrayFromJSON(view_type, "[\"apple\", \"banana\", \"cherry\"]");
auto right = ArrayFromJSON(view_type, "[\"alpha\", \"beta\", \"gamma\"]");
// Call if_else(cond, left, right)
auto result = arrow::compute::IfElse(cond, left, right);
ASSERT_OK(result.status());
}Or in Python:
import pyarrow as pa
import pyarrow.compute as pc
cond = pa.array([True, False, True])
left = pa.array(["apple", "banana", "cherry"], type=pa.string_view())
right = pa.array(["alpha", "beta", "gamma"], type=pa.string_view())
pc.if_else(cond, left, right)Expected:
Returns a string_view array: ["apple", "beta", "cherry"].
Actual:
ArrowNotImplementedError: Function 'if_else' has no kernel matching input types (boolean, string_view, string_view)
Similarly:
ArrowNotImplementedError: Function 'coalesce' has no kernel matching input types (string_view, string_view)
ArrowNotImplementedError: Function 'case_when' has no kernel matching input types (boolean, string_view, string_view)
ArrowNotImplementedError: Function 'choose' has no kernel matching input types (int8, string_view, string_view)
Reproduced on current main across all platforms. This is a type-matrix parity gap in Arrow C++ compute.
Suggested fix
Add zero-allocation direct dispatch for utf8_view and binary_view in cpp/src/arrow/compute/kernels/scalar_if_else.cc:
- Because
BinaryView/StringViewvalues are represented as 16-byte view descriptors (arrow::util::BinaryViewType::c_type), conditional selection is extremely efficient:- The kernel can copy the selected 16-byte descriptors directly into the output array's data buffer.
- The data buffers referenced by the input arrays can be gathered and appended to the output
ArrayData::bufferswithout copying string payloads.
- Register
Type::STRING_VIEWandType::BINARY_VIEWacrossif_else,coalesce,case_when, andchoose. - Add tests in
cpp/src/arrow/compute/kernels/scalar_if_else_test.ccverifying:- Inline short strings (<= 12 bytes) and out-of-line strings (> 12 bytes).
- Sliced arrays with non-zero offsets (
left.Slice(1, 2)). - Array-array, scalar-array, and array-scalar permutations.
- All-null conditions and null input views.
Component(s)
C++, Compute
Activity
umtong commentedon Oct 26, 2026
I'd like to work on this. I'll cover all four conditional kernels, including sliced arrays, nulls, scalar inputs, and the lifetime of out-of-line buffers.