diff --git a/cpp/src/arrow/compute/kernels/aggregate_test.cc b/cpp/src/arrow/compute/kernels/aggregate_test.cc index 1b3af3ffb644e..5296928ce055c 100644 --- a/cpp/src/arrow/compute/kernels/aggregate_test.cc +++ b/cpp/src/arrow/compute/kernels/aggregate_test.cc @@ -2047,6 +2047,134 @@ TEST(TestDecimalMinMaxKernel, Decimals) { } } +TEST(TestNullMinMaxKernel, Basics) { + auto item_ty = null(); + auto ty = struct_({field("min", item_ty), field("max", item_ty)}); + Datum result = ScalarFromJSON(ty, "[null, null]"); + EXPECT_THAT(MinMax(ScalarFromJSON(item_ty, "null")), ResultWith(result)); + EXPECT_THAT(MinMax(ArrayFromJSON(item_ty, "[]")), ResultWith(result)); + EXPECT_THAT(MinMax(ArrayFromJSON(item_ty, "[null]")), ResultWith(result)); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(item_ty, {"[null]", "[]", "[null, null]"})), + ResultWith(result)); +} + +template +class TestBaseBinaryMinMaxKernel : public ::testing::Test {}; +TYPED_TEST_SUITE(TestBaseBinaryMinMaxKernel, BaseBinaryArrowTypes); +TYPED_TEST(TestBaseBinaryMinMaxKernel, Basics) { + std::vector chunked_input1 = {R"(["cc", "", "aa", "b", "c"])", + R"(["d", "", null, "b", "c"])"}; + std::vector chunked_input2 = {R"(["cc", null, "aa", "b", "c"])", + R"(["d", "", "aa", "b", "c"])"}; + std::vector chunked_input3 = {R"(["cc", "", "aa", "b", null])", + R"(["d", "", null, "b", "c"])"}; + auto ty = std::make_shared(); + auto res_ty = struct_({field("min", ty), field("max", ty)}); + Datum null = ScalarFromJSON(res_ty, R"([null, null])"); + + // SKIP nulls by default + EXPECT_THAT(MinMax(ArrayFromJSON(ty, R"([])")), ResultWith(null)); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, R"([null, null, null])")), ResultWith(null)); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0])), + ResultWith(ScalarFromJSON(res_ty, R"(["", "cc"])"))); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0])), + ResultWith(ScalarFromJSON(res_ty, R"(["aa", "cc"])"))); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1)), + ResultWith(ScalarFromJSON(res_ty, R"(["", "d"])"))); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input2)), + ResultWith(ScalarFromJSON(res_ty, R"(["", "d"])"))); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input3)), + ResultWith(ScalarFromJSON(res_ty, R"(["", "d"])"))); + + EXPECT_THAT(MinMax(MakeNullScalar(ty)), ResultWith(null)); + EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("one")")), + ResultWith(ScalarFromJSON(res_ty, R"(["one", "one"])"))); + + ScalarAggregateOptions options(/*skip_nulls=*/false); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), + ResultWith(ScalarFromJSON(res_ty, R"(["", "cc"])"))); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), + ResultWith(null)); + EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); + EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("one")"), options), + ResultWith(ScalarFromJSON(res_ty, R"(["one", "one"])"))); + + options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/9); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), ResultWith(null)); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), + ResultWith(ScalarFromJSON(res_ty, R"(["", "d"])"))); + EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); + EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("one")"), options), ResultWith(null)); + + options = ScalarAggregateOptions(/*skip_nulls=*/false, /*min_count=*/4); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), + ResultWith(ScalarFromJSON(res_ty, R"(["", "cc"])"))); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), + ResultWith(null)); + EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); + EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("one")"), options), ResultWith(null)); +} + +TEST(TestFixedSizeBinaryMinMaxKernel, Basics) { + auto ty = fixed_size_binary(2); + std::vector chunked_input1 = {R"(["cd", "aa", "ab", "bb", "cc"])", + R"(["da", "aa", null, "bb", "cc"])"}; + std::vector chunked_input2 = {R"(["cd", null, "ab", "bb", "cc"])", + R"(["da", "aa", "ab", "bb", "cc"])"}; + std::vector chunked_input3 = {R"(["cd", "aa", "ab", "bb", null])", + R"(["da", "aa", null, "bb", "cc"])"}; + auto res_ty = struct_({field("min", ty), field("max", ty)}); + Datum null = ScalarFromJSON(res_ty, R"([null, null])"); + + // SKIP nulls by default + EXPECT_THAT(MinMax(ArrayFromJSON(ty, R"([])")), ResultWith(null)); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, R"([null, null, null])")), ResultWith(null)); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0])), + ResultWith(ScalarFromJSON(res_ty, R"(["aa", "cd"])"))); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0])), + ResultWith(ScalarFromJSON(res_ty, R"(["ab", "cd"])"))); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1)), + ResultWith(ScalarFromJSON(res_ty, R"(["aa", "da"])"))); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input2)), + ResultWith(ScalarFromJSON(res_ty, R"(["aa", "da"])"))); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input3)), + ResultWith(ScalarFromJSON(res_ty, R"(["aa", "da"])"))); + + EXPECT_THAT(MinMax(MakeNullScalar(ty)), ResultWith(null)); + EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("aa")")), + ResultWith(ScalarFromJSON(res_ty, R"(["aa", "aa"])"))); + + ScalarAggregateOptions options(/*skip_nulls=*/false); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), + ResultWith(ScalarFromJSON(res_ty, R"(["aa", "cd"])"))); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), + ResultWith(null)); + EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); + EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("aa")"), options), + ResultWith(ScalarFromJSON(res_ty, R"(["aa", "aa"])"))); + + options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/9); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), ResultWith(null)); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), + ResultWith(ScalarFromJSON(res_ty, R"(["aa", "da"])"))); + EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); + EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("aa")"), options), ResultWith(null)); + + options = ScalarAggregateOptions(/*skip_nulls=*/false, /*min_count=*/4); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), + ResultWith(ScalarFromJSON(res_ty, R"(["aa", "cd"])"))); + EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); + EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), + ResultWith(null)); + EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); + EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("aa")"), options), ResultWith(null)); +} + TEST(TestDictionaryMinMaxKernel, DecimalsValue) { ScalarAggregateOptions options; std::shared_ptr dict_ty; @@ -2058,7 +2186,13 @@ TEST(TestDictionaryMinMaxKernel, DecimalsValue) { dict_ty = dictionary(index_type, value_ty_); ty = struct_({field("min", value_ty_), field("max", value_ty_)}); + auto chunk1 = DictArrayFromJSON(dict_ty, R"([null, 0])", R"(["5.10"])"); + auto chunk2 = DictArrayFromJSON(dict_ty, R"([0, 1, 1])", R"(["3.10", "-1.23"])"); + ASSERT_OK_AND_ASSIGN(auto chunked, ChunkedArray::Make({chunk1, chunk2})); + options = ScalarAggregateOptions(/*skip_nulls=*/true); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": "-1.23", "max": "5.10"})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([0, 1, 1, 0])", R"(["5.10", "-1.23"])"), options), @@ -2081,6 +2215,8 @@ TEST(TestDictionaryMinMaxKernel, DecimalsValue) { ResultWith(ScalarFromJSON(ty, R"({"min": "1.00", "max": "1.00"})"))); options = ScalarAggregateOptions(/*skip_nulls=*/false); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([null, 3, 1, 1, 4, 0, 2, null])", R"(["5.10", "-1.23", "2.00", "3.45", "4.56"])"), @@ -2093,6 +2229,8 @@ TEST(TestDictionaryMinMaxKernel, DecimalsValue) { ResultWith(ScalarFromJSON(ty, R"({"min": "-1.23", "max": "5.10"})"))); options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/0); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": "-1.23", "max": "5.10"})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([null, null, null])", R"([])"), options), ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); @@ -2100,6 +2238,8 @@ TEST(TestDictionaryMinMaxKernel, DecimalsValue) { ResultWith(ScalarFromJSON(ty, R"({"min": "1.00", "max": "1.00"})"))); options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/5); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([0, 1, 1, 0])", R"(["5.10", "-1.23"])"), options), @@ -2111,6 +2251,8 @@ TEST(TestDictionaryMinMaxKernel, DecimalsValue) { ResultWith(ScalarFromJSON(ty, R"({"min": "-1.23", "max": "5.10"})"))); options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/1); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": "-1.23", "max": "5.10"})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([null, null, null])", R"([])"), options), ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); @@ -2172,7 +2314,13 @@ TEST(TestDictionaryMinMaxKernel, IntegersValue) { dict_ty = dictionary(index_type, value_ty_); ty = struct_({field("min", value_ty_), field("max", value_ty_)}); + auto chunk1 = DictArrayFromJSON(dict_ty, R"([null, 0])", R"([5])"); + auto chunk2 = DictArrayFromJSON(dict_ty, R"([0, 1, 1])", R"([3, 1])"); + ASSERT_OK_AND_ASSIGN(auto chunked, ChunkedArray::Make({chunk1, chunk2})); + options = ScalarAggregateOptions(/*skip_nulls=*/true); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": 1, "max": 5})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([0, 1, 2, 3, 4])", R"([5, 1, 2, 3, 4])"), options), @@ -2191,6 +2339,8 @@ TEST(TestDictionaryMinMaxKernel, IntegersValue) { ResultWith(ScalarFromJSON(ty, R"({"min": 3, "max": 9})"))); options = ScalarAggregateOptions(/*skip_nulls=*/false); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([0, 1, 2, 3, 4])", R"([5, 1, 2, 3, 4])"), options), @@ -2209,6 +2359,8 @@ TEST(TestDictionaryMinMaxKernel, IntegersValue) { ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/0); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": 1, "max": 5})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([null, null, null])", R"([])"), options), ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); @@ -2216,6 +2368,8 @@ TEST(TestDictionaryMinMaxKernel, IntegersValue) { ResultWith(ScalarFromJSON(ty, R"({"min": 1, "max": 1})"))); options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/5); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([0, 1, 1, 0])", R"([5, 1])"), options), ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); @@ -2226,6 +2380,8 @@ TEST(TestDictionaryMinMaxKernel, IntegersValue) { ResultWith(ScalarFromJSON(ty, R"({"min": 1, "max": 5})"))); options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/1); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": 1, "max": 5})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([null, null, null])", R"([])"), options), ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); @@ -2247,7 +2403,13 @@ TEST(TestDictionaryMinMaxKernel, FloatsValue) { dict_ty = dictionary(index_type, value_ty_); ty = struct_({field("min", value_ty_), field("max", value_ty_)}); + auto chunk1 = DictArrayFromJSON(dict_ty, R"([null, 0])", R"([5])"); + auto chunk2 = DictArrayFromJSON(dict_ty, R"([0, 1, 1])", R"([-Inf, 1])"); + ASSERT_OK_AND_ASSIGN(auto chunked, ChunkedArray::Make({chunk1, chunk2})); + options = ScalarAggregateOptions(/*skip_nulls=*/true); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": -Inf, "max": 5})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([0, 1, 2, 3, 4])", R"([5, 1, 2, 3, 4])"), options), @@ -2266,6 +2428,8 @@ TEST(TestDictionaryMinMaxKernel, FloatsValue) { ResultWith(ScalarFromJSON(ty, R"({"min": -Inf, "max": 5})"))); options = ScalarAggregateOptions(/*skip_nulls=*/false); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([0, 1, 2, 3, 4])", R"([5, 1, 2, 3, 4])"), options), @@ -2284,6 +2448,8 @@ TEST(TestDictionaryMinMaxKernel, FloatsValue) { ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/0); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": -Inf, "max": 5})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([null, null, null])", R"([])"), options), ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); @@ -2291,6 +2457,8 @@ TEST(TestDictionaryMinMaxKernel, FloatsValue) { ResultWith(ScalarFromJSON(ty, R"({"min": 1, "max": 1})"))); options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/5); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([0, 1, 1, 0])", R"([5, 1])"), options), ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); @@ -2301,6 +2469,8 @@ TEST(TestDictionaryMinMaxKernel, FloatsValue) { ResultWith(ScalarFromJSON(ty, R"({"min": 1, "max": 5})"))); options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/1); + EXPECT_THAT(MinMax(chunked, options), + ResultWith(ScalarFromJSON(ty, R"({"min": -Inf, "max": 5})"))); EXPECT_THAT( MinMax(DictArrayFromJSON(dict_ty, R"([null, null, null])", R"([])"), options), ResultWith(ScalarFromJSON(ty, R"({"min": null, "max": null})"))); @@ -2329,134 +2499,6 @@ TEST(TestDictionaryMinMaxKernel, NullValue) { } } -TEST(TestNullMinMaxKernel, Basics) { - auto item_ty = null(); - auto ty = struct_({field("min", item_ty), field("max", item_ty)}); - Datum result = ScalarFromJSON(ty, "[null, null]"); - EXPECT_THAT(MinMax(ScalarFromJSON(item_ty, "null")), ResultWith(result)); - EXPECT_THAT(MinMax(ArrayFromJSON(item_ty, "[]")), ResultWith(result)); - EXPECT_THAT(MinMax(ArrayFromJSON(item_ty, "[null]")), ResultWith(result)); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(item_ty, {"[null]", "[]", "[null, null]"})), - ResultWith(result)); -} - -template -class TestBaseBinaryMinMaxKernel : public ::testing::Test {}; -TYPED_TEST_SUITE(TestBaseBinaryMinMaxKernel, BaseBinaryArrowTypes); -TYPED_TEST(TestBaseBinaryMinMaxKernel, Basics) { - std::vector chunked_input1 = {R"(["cc", "", "aa", "b", "c"])", - R"(["d", "", null, "b", "c"])"}; - std::vector chunked_input2 = {R"(["cc", null, "aa", "b", "c"])", - R"(["d", "", "aa", "b", "c"])"}; - std::vector chunked_input3 = {R"(["cc", "", "aa", "b", null])", - R"(["d", "", null, "b", "c"])"}; - auto ty = std::make_shared(); - auto res_ty = struct_({field("min", ty), field("max", ty)}); - Datum null = ScalarFromJSON(res_ty, R"([null, null])"); - - // SKIP nulls by default - EXPECT_THAT(MinMax(ArrayFromJSON(ty, R"([])")), ResultWith(null)); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, R"([null, null, null])")), ResultWith(null)); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0])), - ResultWith(ScalarFromJSON(res_ty, R"(["", "cc"])"))); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0])), - ResultWith(ScalarFromJSON(res_ty, R"(["aa", "cc"])"))); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1)), - ResultWith(ScalarFromJSON(res_ty, R"(["", "d"])"))); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input2)), - ResultWith(ScalarFromJSON(res_ty, R"(["", "d"])"))); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input3)), - ResultWith(ScalarFromJSON(res_ty, R"(["", "d"])"))); - - EXPECT_THAT(MinMax(MakeNullScalar(ty)), ResultWith(null)); - EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("one")")), - ResultWith(ScalarFromJSON(res_ty, R"(["one", "one"])"))); - - ScalarAggregateOptions options(/*skip_nulls=*/false); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), - ResultWith(ScalarFromJSON(res_ty, R"(["", "cc"])"))); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), - ResultWith(null)); - EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); - EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("one")"), options), - ResultWith(ScalarFromJSON(res_ty, R"(["one", "one"])"))); - - options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/9); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), ResultWith(null)); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), - ResultWith(ScalarFromJSON(res_ty, R"(["", "d"])"))); - EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); - EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("one")"), options), ResultWith(null)); - - options = ScalarAggregateOptions(/*skip_nulls=*/false, /*min_count=*/4); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), - ResultWith(ScalarFromJSON(res_ty, R"(["", "cc"])"))); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), - ResultWith(null)); - EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); - EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("one")"), options), ResultWith(null)); -} - -TEST(TestFixedSizeBinaryMinMaxKernel, Basics) { - auto ty = fixed_size_binary(2); - std::vector chunked_input1 = {R"(["cd", "aa", "ab", "bb", "cc"])", - R"(["da", "aa", null, "bb", "cc"])"}; - std::vector chunked_input2 = {R"(["cd", null, "ab", "bb", "cc"])", - R"(["da", "aa", "ab", "bb", "cc"])"}; - std::vector chunked_input3 = {R"(["cd", "aa", "ab", "bb", null])", - R"(["da", "aa", null, "bb", "cc"])"}; - auto res_ty = struct_({field("min", ty), field("max", ty)}); - Datum null = ScalarFromJSON(res_ty, R"([null, null])"); - - // SKIP nulls by default - EXPECT_THAT(MinMax(ArrayFromJSON(ty, R"([])")), ResultWith(null)); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, R"([null, null, null])")), ResultWith(null)); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0])), - ResultWith(ScalarFromJSON(res_ty, R"(["aa", "cd"])"))); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0])), - ResultWith(ScalarFromJSON(res_ty, R"(["ab", "cd"])"))); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1)), - ResultWith(ScalarFromJSON(res_ty, R"(["aa", "da"])"))); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input2)), - ResultWith(ScalarFromJSON(res_ty, R"(["aa", "da"])"))); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input3)), - ResultWith(ScalarFromJSON(res_ty, R"(["aa", "da"])"))); - - EXPECT_THAT(MinMax(MakeNullScalar(ty)), ResultWith(null)); - EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("aa")")), - ResultWith(ScalarFromJSON(res_ty, R"(["aa", "aa"])"))); - - ScalarAggregateOptions options(/*skip_nulls=*/false); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), - ResultWith(ScalarFromJSON(res_ty, R"(["aa", "cd"])"))); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), - ResultWith(null)); - EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); - EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("aa")"), options), - ResultWith(ScalarFromJSON(res_ty, R"(["aa", "aa"])"))); - - options = ScalarAggregateOptions(/*skip_nulls=*/true, /*min_count=*/9); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), ResultWith(null)); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), - ResultWith(ScalarFromJSON(res_ty, R"(["aa", "da"])"))); - EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); - EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("aa")"), options), ResultWith(null)); - - options = ScalarAggregateOptions(/*skip_nulls=*/false, /*min_count=*/4); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input1[0]), options), - ResultWith(ScalarFromJSON(res_ty, R"(["aa", "cd"])"))); - EXPECT_THAT(MinMax(ArrayFromJSON(ty, chunked_input2[0]), options), ResultWith(null)); - EXPECT_THAT(MinMax(ChunkedArrayFromJSON(ty, chunked_input1), options), - ResultWith(null)); - EXPECT_THAT(MinMax(MakeNullScalar(ty), options), ResultWith(null)); - EXPECT_THAT(MinMax(ScalarFromJSON(ty, R"("aa")"), options), ResultWith(null)); -} - template struct MinMaxResult { using T = typename ArrowType::c_type;