diff --git a/cpp/src/arrow/c/bridge.cc b/cpp/src/arrow/c/bridge.cc index 002096399d2..f27f5618563 100644 --- a/cpp/src/arrow/c/bridge.cc +++ b/cpp/src/arrow/c/bridge.cc @@ -746,8 +746,9 @@ class FormatStringParser { template Result> ParseInts(std::string_view v) { - auto parts = Split(v); std::vector result; + if (v.empty()) return result; + auto parts = Split(v); result.reserve(parts.size()); for (const auto& p : parts) { ARROW_ASSIGN_OR_RAISE(auto i, ParseInt(p)); diff --git a/cpp/src/arrow/c/bridge_test.cc b/cpp/src/arrow/c/bridge_test.cc index a54da82e10c..170d7379df2 100644 --- a/cpp/src/arrow/c/bridge_test.cc +++ b/cpp/src/arrow/c/bridge_test.cc @@ -408,12 +408,16 @@ TEST_F(TestSchemaExport, Union) { auto type = dense_union({field_a, field_b}, {42, 43}); TestNested(type, {"+ud:42,43", "c", "b"}, {"", "a", "b"}, {ARROW_FLAG_NULLABLE, ARROW_FLAG_NULLABLE, 0}); + TestNested(dense_union(arrow::FieldVector{}, std::vector{}), {"+ud:"}, {""}, + {ARROW_FLAG_NULLABLE}); // Sparse field_a = field("a", int8(), /*nullable=*/false); field_b = field("b", boolean()); type = sparse_union({field_a, field_b}, {42, 43}); TestNested(type, {"+us:42,43", "c", "b"}, {"", "a", "b"}, {ARROW_FLAG_NULLABLE, 0, ARROW_FLAG_NULLABLE}); + TestNested(sparse_union(arrow::FieldVector{}, std::vector{}), {"+us:"}, {""}, + {ARROW_FLAG_NULLABLE}); } std::string GetIndexFormat(Type::type type_id) { @@ -2625,6 +2629,7 @@ TEST_F(TestSchemaRoundtrip, Struct) { TestWithTypeFactory([&]() { return struct_({f1, f2}); }); f2 = f2->WithMetadata(key_value_metadata(kMetadataKeys2, kMetadataValues2)); TestWithTypeFactory([&]() { return struct_({f1, f2}); }); + TestWithTypeFactory([&]() { return struct_(arrow::FieldVector{}); }); } TEST_F(TestSchemaRoundtrip, Union) { @@ -2632,6 +2637,10 @@ TEST_F(TestSchemaRoundtrip, Union) { auto f2 = field("f2", list(decimal(19, 4))); auto type_codes = std::vector{42, 43}; + TestWithTypeFactory( + [&]() { return dense_union(arrow::FieldVector{}, std::vector{}); }); + TestWithTypeFactory( + [&]() { return sparse_union(arrow::FieldVector{}, std::vector{}); }); TestWithTypeFactory([&]() { return sparse_union({f1, f2}, type_codes); }); f2 = f2->WithMetadata(key_value_metadata(kMetadataKeys2, kMetadataValues2)); TestWithTypeFactory([&]() { return dense_union({f1, f2}, type_codes); }); @@ -2871,6 +2880,12 @@ TEST_F(TestArrayRoundtrip, Struct) { TestWithJSON(type, "[[4, true], [5, null]]"); TestWithJSONSliced(type, "[[4, true], [5, null], [6, false]]"); + + // With no fields + type = struct_({}); + TestWithJSON(type, "[]"); + TestWithJSON(type, "[[], null, [], null, []]"); + TestWithJSONSliced(type, "[[], null, [], null, []]"); } TEST_F(TestArrayRoundtrip, Map) { @@ -2898,6 +2913,15 @@ TEST_F(TestArrayRoundtrip, Union) { TestWithJSON(type, json); TestWithJSONSliced(type, json); } + + // With no fields + fields = {}; + type_codes = {}; + union_types = {sparse_union(fields, type_codes), dense_union(fields, type_codes)}; + + for (const auto& type : union_types) { + TestWithJSON(type, "[]"); + } } TEST_F(TestArrayRoundtrip, Dictionary) {