Skip to content

[C++][Compute] Conditional compute kernels (if_else, coalesce, case_when, choose) do not support string_view or binary_view #55255

Open

Description

@Awesome06

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:

  1. Because BinaryView / StringView values 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::buffers without copying string payloads.
  2. Register Type::STRING_VIEW and Type::BINARY_VIEW across if_else, coalesce, case_when, and choose.
  3. Add tests in cpp/src/arrow/compute/kernels/scalar_if_else_test.cc verifying:
    • 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

  1. umtong commented on Oct 26, 2026

    @umtong

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions