diff --git a/src/v/pandaproxy/schema_registry/protobuf.cc b/src/v/pandaproxy/schema_registry/protobuf.cc index 11ccc8451ab41..8d5cdcb829d8d 100644 --- a/src/v/pandaproxy/schema_registry/protobuf.cc +++ b/src/v/pandaproxy/schema_registry/protobuf.cc @@ -771,6 +771,9 @@ struct compatibility_checker { for (int i = 0; i < writer->nested_type_count(); ++i) { auto w = writer->nested_type(i); + if (w->options().has_map_entry()) { + continue; + } auto r = reader->FindNestedTypeByName(w->name()); if (!r) { compat_result.emplace( diff --git a/src/v/pandaproxy/schema_registry/test/compatibility_protobuf.cc b/src/v/pandaproxy/schema_registry/test/compatibility_protobuf.cc index 4acbb02e962c3..f08375a6f5cf1 100644 --- a/src/v/pandaproxy/schema_registry/test/compatibility_protobuf.cc +++ b/src/v/pandaproxy/schema_registry/test/compatibility_protobuf.cc @@ -1830,6 +1830,71 @@ service FooService { )")); } +SEASTAR_THREAD_TEST_CASE(test_protobuf_compatibility_remove_map_field) { + constexpr std::string_view with_map = R"(syntax = "proto3"; + +message Product { + string name = 1; + map tags = 10; +} +)"; + constexpr std::string_view without_map = R"(syntax = "proto3"; + +message Product { + string name = 1; +} +)"; + + BOOST_REQUIRE(check_compatible( + pps::compatibility_level::backward, without_map, with_map)); + BOOST_REQUIRE(check_compatible( + pps::compatibility_level::backward_transitive, without_map, with_map)); + BOOST_REQUIRE( + check_compatible(pps::compatibility_level::full, without_map, with_map)); + BOOST_REQUIRE(check_compatible( + pps::compatibility_level::full_transitive, without_map, with_map)); + + BOOST_REQUIRE(check_compatible( + pps::compatibility_level::forward, with_map, without_map)); + BOOST_REQUIRE(check_compatible( + pps::compatibility_level::forward_transitive, with_map, without_map)); +} + +SEASTAR_THREAD_TEST_CASE(test_protobuf_compatibility_map_in_nested_message) { + constexpr std::string_view with_map = R"(syntax = "proto3"; + +message Outer { + message Inner { + string id = 1; + map tags = 2; + } + Inner inner = 1; +} +)"; + constexpr std::string_view without_map = R"(syntax = "proto3"; + +message Outer { + message Inner { + string id = 1; + } + Inner inner = 1; +} +)"; + BOOST_REQUIRE(check_compatible( + pps::compatibility_level::backward, without_map, with_map)); + BOOST_REQUIRE(check_compatible( + pps::compatibility_level::backward_transitive, without_map, with_map)); + BOOST_REQUIRE( + check_compatible(pps::compatibility_level::full, without_map, with_map)); + BOOST_REQUIRE(check_compatible( + pps::compatibility_level::full_transitive, without_map, with_map)); + + BOOST_REQUIRE(check_compatible( + pps::compatibility_level::forward, with_map, without_map)); + BOOST_REQUIRE(check_compatible( + pps::compatibility_level::forward_transitive, with_map, without_map)); +} + SEASTAR_THREAD_TEST_CASE(test_protobuf_compatibility_message_removed) { BOOST_REQUIRE(!check_compatible( pps::compatibility_level::backward,