diff --git a/cpp/src/arrow/compute/kernels/codegen_internal.h b/cpp/src/arrow/compute/kernels/codegen_internal.h index 15a946fbdbb8..d33ffacb2f55 100644 --- a/cpp/src/arrow/compute/kernels/codegen_internal.h +++ b/cpp/src/arrow/compute/kernels/codegen_internal.h @@ -350,6 +350,22 @@ struct ArrayIterator> { } }; +template +struct ArrayIterator> { + const BinaryViewType::c_type* views; + const std::shared_ptr* data_buffers; + int64_t position; + + explicit ArrayIterator(const ArraySpan& arr) + : views(arr.GetValues(1)), + data_buffers(arr.GetVariadicBuffers().data()), + position(0) {} + + std::string_view operator()() { + return util::FromBinaryView(views[position++], data_buffers); + } +}; + template <> struct ArrayIterator { const ArraySpan& arr; diff --git a/cpp/src/arrow/compute/kernels/scalar_compare.cc b/cpp/src/arrow/compute/kernels/scalar_compare.cc index 773a3f684bd5..3dfd66655e5f 100644 --- a/cpp/src/arrow/compute/kernels/scalar_compare.cc +++ b/cpp/src/arrow/compute/kernels/scalar_compare.cc @@ -433,6 +433,12 @@ std::shared_ptr MakeCompareFunction(std::string name, FunctionDo GenerateVarBinaryBase(*ty); DCHECK_OK(func->AddKernel({ty, ty}, boolean(), std::move(exec))); } + for (const auto& ty : BinaryViewTypes()) { + auto exec = + GenerateVarBinaryViewBase( + *ty); + DCHECK_OK(func->AddKernel({ty, ty}, boolean(), std::move(exec))); + } for (const auto id : {Type::DECIMAL128, Type::DECIMAL256}) { auto exec = GenerateDecimal(id); diff --git a/cpp/src/arrow/compute/kernels/scalar_compare_test.cc b/cpp/src/arrow/compute/kernels/scalar_compare_test.cc index 23c7ab21bd20..2aae5bf2ee90 100644 --- a/cpp/src/arrow/compute/kernels/scalar_compare_test.cc +++ b/cpp/src/arrow/compute/kernels/scalar_compare_test.cc @@ -1196,6 +1196,55 @@ TEST_F(TestStringCompareKernel, RandomCompareArrayArray) { } } +TEST(TestBinaryViewCompareKernel, ArrayArray) { + const auto cases = std::vector>{binary_view(), utf8_view()}; + const auto expected = std::vector>{ + {"equal", "[true, false, false, false, false, false, null]"}, + {"not_equal", "[false, true, true, true, true, true, null]"}, + {"greater", "[false, false, false, false, false, true, null]"}, + {"greater_equal", "[true, false, false, false, false, true, null]"}, + {"less", "[false, true, true, true, true, false, null]"}, + {"less_equal", "[true, true, true, true, true, false, null]"}}; + + for (const auto& ty : cases) { + auto lhs = + ArrayFromJSON(ty, R"(["", "abc", "abcdefghijkl", "abcdefghijklm", "prefix_same_A", + "samepref_size", null])"); + auto rhs = ArrayFromJSON( + ty, R"(["", "abd", "abcdefghijklm", "abcdefghijklz", "prefix_same_B", + "samepref", null])"); + + CheckScalarBinary("equal", ArrayFromJSON(ty, R"([])"), ArrayFromJSON(ty, R"([])"), + ArrayFromJSON(boolean(), R"([])")); + CheckScalarBinary("equal", ArrayFromJSON(ty, R"([null])"), + ArrayFromJSON(ty, R"([null])"), + ArrayFromJSON(boolean(), R"([null])")); + for (const auto& function_and_expected : expected) { + CheckScalarBinary(function_and_expected.first, lhs, rhs, + ArrayFromJSON(boolean(), function_and_expected.second)); + } + } +} + +TEST(TestBinaryViewCompareKernel, ArrayScalar) { + for (const auto& ty : {binary_view(), utf8_view()}) { + auto arr = ArrayFromJSON(ty, R"(["", "abc", "abcdefghijklmnop", null])"); + auto scalar = ScalarFromJSON(ty, R"("abc")"); + auto null_scalar = ScalarFromJSON(ty, "null"); + + CheckScalarBinary("equal", arr, scalar, + ArrayFromJSON(boolean(), R"([false, true, false, null])")); + CheckScalarBinary("equal", scalar, arr, + ArrayFromJSON(boolean(), R"([false, true, false, null])")); + CheckScalarBinary("greater", arr, scalar, + ArrayFromJSON(boolean(), R"([false, false, true, null])")); + CheckScalarBinary("less", scalar, arr, + ArrayFromJSON(boolean(), R"([false, false, true, null])")); + CheckScalarBinary("equal", arr, null_scalar, + ArrayFromJSON(boolean(), R"([null, null, null, null])")); + } +} + template class TestVarArgsCompare : public ::testing::Test { protected: