Skip to content

Commit 2e72e87

Browse files
committed
add test for FSL, List and Map to String
1 parent 361d6bc commit 2e72e87

File tree

2 files changed

+123
-8
lines changed

2 files changed

+123
-8
lines changed

cpp/src/arrow/compute/kernels/scalar_cast_string.cc

+10-2
Original file line numberDiff line numberDiff line change
@@ -547,16 +547,24 @@ struct ListLikeToStringCastFunctor {
547547
end = offsets[i + 1];
548548
}
549549

550-
for (int64_t j = start; j < end; ++j) {
550+
auto append_value = [&](int64_t j) -> Status {
551551
if (j != start) {
552552
ss << ", ";
553553
}
554554
if (values.IsValid(j)) {
555-
ss << std::to_string(values.GetValues<int16_t>(1)[j]);
555+
std::shared_ptr<Scalar> value_scalar;
556+
RETURN_NOT_OK(values.ToArray()->GetScalar(j).Value(&value_scalar));
557+
ss << value_scalar->ToString();
556558
} else {
557559
ss << "null";
558560
}
561+
return Status::OK();
562+
};
563+
564+
for (int64_t j = start; j < end; ++j) {
565+
RETURN_NOT_OK(append_value(j));
559566
}
567+
560568
ss << "]";
561569
RETURN_NOT_OK(builder.Append(ss.str()));
562570
}

cpp/src/arrow/compute/kernels/scalar_cast_test.cc

+113-6
Original file line numberDiff line numberDiff line change
@@ -2275,10 +2275,6 @@ TEST(Cast, BooleanToString) {
22752275
TEST(Cast, ListToPrimitive) {
22762276
ASSERT_RAISES(NotImplemented,
22772277
Cast(*ArrayFromJSON(list(int8()), "[[1, 2], [3, 4]]"), uint8()));
2278-
2279-
ASSERT_RAISES(
2280-
NotImplemented,
2281-
Cast(*ArrayFromJSON(list(binary()), R"([["1", "2"], ["3", "4"]])"), utf8()));
22822278
}
22832279

22842280
using make_list_t = std::shared_ptr<DataType>(const std::shared_ptr<DataType>&);
@@ -2429,6 +2425,40 @@ TEST(Cast, FSLToList) {
24292425
CheckCast(fsl_int32, ArrayFromJSON(fixed_size_list(int16(), 1), "[[32689]]"), options);
24302426
}
24312427

2428+
TEST(Cast, FSLToString) {
2429+
auto CheckFSLToStringCast = [](const std::shared_ptr<DataType>& fsl_type,
2430+
const std::string& fsl_json,
2431+
const std::string& expected_str) {
2432+
std::shared_ptr<Array> src = ArrayFromJSON(fsl_type, fsl_json);
2433+
ASSERT_OK_AND_ASSIGN(auto casted_str, Cast(*src, utf8()));
2434+
2435+
std::shared_ptr<Array> expected_array = ArrayFromJSON(utf8(), expected_str);
2436+
ASSERT_TRUE(casted_str->Equals(expected_array)) << casted_str->ToString();
2437+
};
2438+
2439+
// Example with int32 list
2440+
std::shared_ptr<DataType> fsl_type = fixed_size_list(int32(), 3);
2441+
const std::string fsl_json = R"([[1, 2, 3], [4, 5, 6], [7, null, 8], null])";
2442+
const std::string expected_str =
2443+
"[\"fixed_size_list<item: int32>[3][1, 2, 3]\", "
2444+
"\"fixed_size_list<item: int32>[3][4, 5, 6]\", "
2445+
"\"fixed_size_list<item: int32>[3][7, null, 8]\", "
2446+
"\"null\"]";
2447+
2448+
CheckFSLToStringCast(fsl_type, fsl_json, expected_str);
2449+
2450+
// Example with nested fixed_size_list<int32> of size 2
2451+
fsl_type = fixed_size_list(fixed_size_list(int32(), 2), 2);
2452+
const std::string nested_fsl_json = R"([[[1, 2], [3, 4]], [[null, 5], null]])";
2453+
const std::string expected_nested_str =
2454+
"[\"fixed_size_list<item: fixed_size_list<item: int32>[2]>[2]"
2455+
"[fixed_size_list<item: int32>[2][1, 2], fixed_size_list<item: int32>[2][3, 4]]\", "
2456+
"\"fixed_size_list<item: fixed_size_list<item: int32>[2]>[2]"
2457+
"[fixed_size_list<item: int32>[2][null, 5], null]\"]";
2458+
2459+
CheckFSLToStringCast(fsl_type, nested_fsl_json, expected_nested_str);
2460+
}
2461+
24322462
TEST(Cast, ListToFSL) {
24332463
CheckCastList(list(int16()), fixed_size_list(int16(), 2),
24342464
"[[0, 1], [2, 3], null, [null, 5], null]");
@@ -2476,6 +2506,40 @@ TEST(Cast, ListToFSL) {
24762506
CastOptions::Safe(fixed_size_list(int32(), 3))));
24772507
}
24782508

2509+
TEST(Cast, ListToString) {
2510+
auto CheckListToStringCast = [](const std::shared_ptr<DataType>& list_type,
2511+
const std::string& list_json,
2512+
const std::string& expected_str) {
2513+
std::shared_ptr<Array> src = ArrayFromJSON(list_type, list_json);
2514+
ASSERT_OK_AND_ASSIGN(auto casted_str, Cast(*src, utf8()));
2515+
2516+
std::shared_ptr<Array> expected_array = ArrayFromJSON(utf8(), expected_str);
2517+
ASSERT_TRUE(casted_str->Equals(expected_array)) << casted_str->ToString();
2518+
};
2519+
2520+
// Example with int32 list
2521+
std::shared_ptr<DataType> list_type = list(int32());
2522+
const std::string list_json = R"([[1, 2, 3], [4, 5], [6], []])";
2523+
const std::string expected_str =
2524+
R"(["list<item: int32>[1, 2, 3]",
2525+
"list<item: int32>[4, 5]",
2526+
"list<item: int32>[6]",
2527+
"list<item: int32>[]"])";
2528+
2529+
CheckListToStringCast(list_type, list_json, expected_str);
2530+
2531+
// Example with nested list of int32
2532+
list_type = list(list(int32()));
2533+
const std::string nested_list_json = R"([[[1, 2], [3, 4]], [[5], [6, 7]], [[]], []])";
2534+
const std::string expected_nested_str =
2535+
R"(["list<item: list<item: int32>>[list<item: int32>[1, 2], list<item: int32>[3, 4]]",
2536+
"list<item: list<item: int32>>[list<item: int32>[5], list<item: int32>[6, 7]]",
2537+
"list<item: list<item: int32>>[list<item: int32>[]]",
2538+
"list<item: list<item: int32>>[]"])";
2539+
2540+
CheckListToStringCast(list_type, nested_list_json, expected_nested_str);
2541+
}
2542+
24792543
TEST(Cast, CastMap) {
24802544
const std::string map_json =
24812545
"[[[\"x\", 1], [\"y\", 8], [\"z\", 9]], [[\"x\", 6]], [[\"y\", 36]]]";
@@ -2509,9 +2573,9 @@ TEST(Cast, CastMap) {
25092573
std::shared_ptr<DataType> dst_type = map(utf8(), field("y", list(field("b", int64()))));
25102574

25112575
std::shared_ptr<Array> src =
2512-
ArrayFromJSON(src_type, "[[[\"1\", [1,2,3]]], [[\"2\", [4,5,6]]]]");
2576+
ArrayFromJSON(src_type, R"([[["1", [1,2,3]]], [["2", [4,5,6]]]])");
25132577
std::shared_ptr<Array> dst =
2514-
ArrayFromJSON(dst_type, "[[[\"1\", [1,2,3]]], [[\"2\", [4,5,6]]]]");
2578+
ArrayFromJSON(dst_type, R"([[["1", [1,2,3]]], [["2", [4,5,6]]]])");
25152579

25162580
CheckCast(src, dst);
25172581

@@ -2524,6 +2588,49 @@ TEST(Cast, CastMap) {
25242588
Cast(src, dst_type));
25252589
}
25262590

2591+
void CheckMapToStringCast(const std::string& map_json,
2592+
const std::string& map_json_nullable,
2593+
const std::vector<std::string>& expected_str,
2594+
const std::vector<std::string>& expected_str_nullable,
2595+
const std::shared_ptr<DataType>& src_type) {
2596+
auto check_cast = [&](const std::string& json,
2597+
const std::vector<std::string>& expected) {
2598+
std::shared_ptr<Array> src = ArrayFromJSON(src_type, json);
2599+
for (int64_t i = 0; i < src->length(); ++i) {
2600+
ASSERT_OK_AND_ASSIGN(auto scalar, src->GetScalar(i));
2601+
ASSERT_OK_AND_ASSIGN(auto casted_str, Cast(scalar, utf8()));
2602+
ASSERT_EQ(casted_str.scalar()->type->id(), utf8()->id());
2603+
ASSERT_EQ(casted_str.scalar()->ToString(), expected[i]);
2604+
}
2605+
};
2606+
2607+
check_cast(map_json, expected_str);
2608+
check_cast(map_json_nullable, expected_str_nullable);
2609+
}
2610+
2611+
TEST(Cast, MapToString) {
2612+
const std::string map_json =
2613+
"[[[\"x\", 1], [\"y\", 8], [\"z\", 9]], [[\"x\", 6]], [[\"y\", 36]]]";
2614+
const std::string map_json_nullable =
2615+
"[[[\"x\", 1], [\"y\", null], [\"z\", 9]], null, [[\"y\", 36]]]";
2616+
2617+
const std::vector<std::string> expected_str = {
2618+
"map<string ('x'), int64 ('y')>[{x:string = x, y:int64 = 1}, "
2619+
"{x:string = y, y:int64 = 8}, {x:string = z, y:int64 = 9}]",
2620+
"map<string ('x'), int64 ('y')>[{x:string = x, y:int64 = 6}]",
2621+
"map<string ('x'), int64 ('y')>[{x:string = y, y:int64 = 36}]"};
2622+
2623+
const std::vector<std::string> expected_str_nullable = {
2624+
"map<string ('x'), int64 ('y')>[{x:string = x, y:int64 = 1}, "
2625+
"{x:string = y, y:int64 = null}, {x:string = z, y:int64 = 9}]",
2626+
"null", "map<string ('x'), int64 ('y')>[{x:string = y, y:int64 = 36}]"};
2627+
2628+
auto src_type =
2629+
std::make_shared<MapType>(field("x", utf8(), false), field("y", int64()));
2630+
CheckMapToStringCast(map_json, map_json_nullable, expected_str, expected_str_nullable,
2631+
src_type);
2632+
}
2633+
25272634
static void CheckStructToStruct(
25282635
const std::vector<std::shared_ptr<DataType>>& value_types) {
25292636
for (const auto& src_value_type : value_types) {

0 commit comments

Comments
 (0)