aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkmokrov <kmokrov@yandex-team.com>2023-11-29 09:33:51 +0300
committerkmokrov <kmokrov@yandex-team.com>2023-11-29 10:05:47 +0300
commitb30b19cb22468f06acf3d2071f1a81e9e470bd57 (patch)
treede65468d57ab37a02ebd7f6df9ccb9382265befa
parent55fc158d4d2d8ae4d9f026e1afac03c7daae294d (diff)
downloadydb-b30b19cb22468f06acf3d2071f1a81e9e470bd57.tar.gz
YTORM-843: Add protobuf map key field type resolve by path
Так как поля, соответствующие `string` и `bytes` в плюсовом коде хранятся, как `TString`, нужен способ, которыый позволил бы их отличать, ведь валидацию `utf8` надо добавлять только для `string`. После этого ПРа можно будет смотреть на протобуфный тип ключа и в зависимости от него добавлять или нет валидацию
-rw-r--r--yt/yt/core/yson/config.cpp2
-rw-r--r--yt/yt/core/yson/protobuf_interop.cpp10
-rw-r--r--yt/yt/core/yson/protobuf_interop.h1
-rw-r--r--yt/yt/core/yson/unittests/protobuf_yson_ut.cpp20
4 files changed, 22 insertions, 11 deletions
diff --git a/yt/yt/core/yson/config.cpp b/yt/yt/core/yson/config.cpp
index 8ced712d57..3f6ccf94de 100644
--- a/yt/yt/core/yson/config.cpp
+++ b/yt/yt/core/yson/config.cpp
@@ -12,4 +12,4 @@ void TProtobufInteropDynamicConfig::Register(TRegistrar registrar)
////////////////////////////////////////////////////////////////////////////////
-} // NYT::NYson
+} // namespace NYT::NYson
diff --git a/yt/yt/core/yson/protobuf_interop.cpp b/yt/yt/core/yson/protobuf_interop.cpp
index 79772200b5..d51b211782 100644
--- a/yt/yt/core/yson/protobuf_interop.cpp
+++ b/yt/yt/core/yson/protobuf_interop.cpp
@@ -661,11 +661,15 @@ TProtobufElement TProtobufField::GetElement(bool insideRepeated) const
{
if (IsRepeated() && !insideRepeated) {
return std::make_unique<TProtobufRepeatedElement>(TProtobufRepeatedElement{
- GetElement(true)
+ GetElement(/*insideRepeated*/ true)
});
} else if (IsYsonMap()) {
+ auto element = GetYsonMapKeyField()->GetElement(/*insideRepeated*/ false);
+ auto* keyElement = std::get_if<std::unique_ptr<TProtobufScalarElement>>(&element);
+ YT_VERIFY(keyElement);
return std::make_unique<TProtobufMapElement>(TProtobufMapElement{
- GetYsonMapValueField()->GetElement(false)
+ .KeyElement = std::move(**keyElement),
+ .Element = GetYsonMapValueField()->GetElement(/*insideRepeated*/ false)
});
} else if (IsYsonString()) {
return std::make_unique<TProtobufAnyElement>();
@@ -889,7 +893,7 @@ protected:
}
}
- void ValidateString(TStringBuf data, TString fieldFullName)
+ void ValidateString(TStringBuf data, TStringBuf fieldFullName)
{
auto config = GetProtobufInteropConfig();
if (config->Utf8Check == EUtf8Check::Disable || IsUtf(data)) {
diff --git a/yt/yt/core/yson/protobuf_interop.h b/yt/yt/core/yson/protobuf_interop.h
index efb2d0321f..3267ac036b 100644
--- a/yt/yt/core/yson/protobuf_interop.h
+++ b/yt/yt/core/yson/protobuf_interop.h
@@ -94,6 +94,7 @@ struct TProtobufRepeatedElement
struct TProtobufMapElement
{
+ TProtobufScalarElement KeyElement;
TProtobufElement Element;
};
diff --git a/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp b/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp
index a8fc7aeef6..f995f3f459 100644
--- a/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp
+++ b/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp
@@ -2153,21 +2153,27 @@ TEST(TResolveProtobufElementByYPath, Repeated)
////////////////////////////////////////////////////////////////////////////////
-void TestMapByYPath(const TYPath& path)
+template <typename ValueElementType>
+void TestMapByYPath(const TYPath& path, int expectedUnderlyingKeyProtoType)
{
auto result = ResolveProtobufElementByYPath(ReflectProtobufMessageType<NYT::NYson::NProto::TMessage>(), path);
- EXPECT_TRUE(std::holds_alternative<std::unique_ptr<TProtobufMapElement>>(result.Element));
+
EXPECT_EQ(path, result.HeadPath);
EXPECT_EQ("", result.TailPath);
+
+ auto* map = std::get_if<std::unique_ptr<TProtobufMapElement>>(&result.Element);
+ ASSERT_TRUE(map);
+ EXPECT_EQ(static_cast<int>((*map)->KeyElement.Type), expectedUnderlyingKeyProtoType);
+ EXPECT_TRUE(std::holds_alternative<std::unique_ptr<ValueElementType>>((*map)->Element));
}
TEST(TResolveProtobufElementByYPath, Map)
{
- TestMapByYPath("/string_to_int32_map");
- TestMapByYPath("/int32_to_int32_map");
- TestMapByYPath("/nested_message_map");
- TestMapByYPath("/nested_message_map/abc/nested_message_map");
- TestMapByYPath("/nested_message1/nested_message_map");
+ TestMapByYPath<TProtobufScalarElement>("/string_to_int32_map", FieldDescriptor::TYPE_STRING);
+ TestMapByYPath<TProtobufScalarElement>("/int32_to_int32_map", FieldDescriptor::TYPE_INT32);
+ TestMapByYPath<TProtobufMessageElement>("/nested_message_map", FieldDescriptor::TYPE_STRING);
+ TestMapByYPath<TProtobufMessageElement>("/nested_message_map/abc/nested_message_map", FieldDescriptor::TYPE_STRING);
+ TestMapByYPath<TProtobufMessageElement>("/nested_message1/nested_message_map", FieldDescriptor::TYPE_STRING);
}
////////////////////////////////////////////////////////////////////////////////