diff options
author | kmokrov <kmokrov@yandex-team.com> | 2023-11-29 09:33:51 +0300 |
---|---|---|
committer | kmokrov <kmokrov@yandex-team.com> | 2023-11-29 10:05:47 +0300 |
commit | b30b19cb22468f06acf3d2071f1a81e9e470bd57 (patch) | |
tree | de65468d57ab37a02ebd7f6df9ccb9382265befa | |
parent | 55fc158d4d2d8ae4d9f026e1afac03c7daae294d (diff) | |
download | ydb-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.cpp | 2 | ||||
-rw-r--r-- | yt/yt/core/yson/protobuf_interop.cpp | 10 | ||||
-rw-r--r-- | yt/yt/core/yson/protobuf_interop.h | 1 | ||||
-rw-r--r-- | yt/yt/core/yson/unittests/protobuf_yson_ut.cpp | 20 |
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); } //////////////////////////////////////////////////////////////////////////////// |