diff options
| author | renadeen <[email protected]> | 2025-08-28 16:41:01 +0300 |
|---|---|---|
| committer | renadeen <[email protected]> | 2025-08-28 17:07:56 +0300 |
| commit | 9be8744bb96ab00cbf25afb60ab54db5cbad95dc (patch) | |
| tree | 963b8d209cb1799bea0ed0aa62d90665d29b33f9 | |
| parent | 64ca6c1c9b620c076cefb3594764cc8205e636b8 (diff) | |
YT-26037: Fix empty polymorphic yson struct
commit_hash:918f0da0ab743372aebb95a69ed93cc6dad32df2
| -rw-r--r-- | yt/yt/core/ytree/polymorphic_yson_struct-inl.h | 15 | ||||
| -rw-r--r-- | yt/yt/core/ytree/polymorphic_yson_struct.h | 2 | ||||
| -rw-r--r-- | yt/yt/core/ytree/unittests/yson_struct_ut.cpp | 39 |
3 files changed, 47 insertions, 9 deletions
diff --git a/yt/yt/core/ytree/polymorphic_yson_struct-inl.h b/yt/yt/core/ytree/polymorphic_yson_struct-inl.h index ed0352c2438..382742609bf 100644 --- a/yt/yt/core/ytree/polymorphic_yson_struct-inl.h +++ b/yt/yt/core/ytree/polymorphic_yson_struct-inl.h @@ -46,6 +46,16 @@ CreateInstance(TEnum value) //////////////////////////////////////////////////////////////////////////////// template <CPolymorphicEnumMapping TMapping> +TPolymorphicYsonStruct<TMapping>::TPolymorphicYsonStruct() +{ + if constexpr (DefaultType_) { + HeldType_ = *DefaultType_; + } else { + HeldType_ = {}; + } +} + +template <CPolymorphicEnumMapping TMapping> TPolymorphicYsonStruct<TMapping>::TPolymorphicYsonStruct(TKey key) : TPolymorphicYsonStruct(key, TMapping::CreateInstance(key)) { } @@ -77,11 +87,6 @@ void TPolymorphicYsonStruct<TMapping>::Load( SerializedStorage_ = TTraits::AsNode(source); IMapNodePtr map = SerializedStorage_->AsMap(); - if (!map || map->GetChildCount() == 0) { - // Empty struct. - return; - } - auto key = map->FindChildValue<TKey>("type"); THROW_ERROR_EXCEPTION_UNLESS( key.has_value() || DefaultType_, diff --git a/yt/yt/core/ytree/polymorphic_yson_struct.h b/yt/yt/core/ytree/polymorphic_yson_struct.h index 50c4b206380..effc27ae034 100644 --- a/yt/yt/core/ytree/polymorphic_yson_struct.h +++ b/yt/yt/core/ytree/polymorphic_yson_struct.h @@ -160,7 +160,7 @@ class TPolymorphicYsonStruct public: using TImplementsYsonStructField = void; - TPolymorphicYsonStruct() = default; + TPolymorphicYsonStruct(); explicit TPolymorphicYsonStruct(TKey key); TPolymorphicYsonStruct(TKey key, TIntrusivePtr<TBase> ptr) noexcept; diff --git a/yt/yt/core/ytree/unittests/yson_struct_ut.cpp b/yt/yt/core/ytree/unittests/yson_struct_ut.cpp index 31217b26b2f..792c5636c76 100644 --- a/yt/yt/core/ytree/unittests/yson_struct_ut.cpp +++ b/yt/yt/core/ytree/unittests/yson_struct_ut.cpp @@ -3478,6 +3478,18 @@ TEST(TYsonStructTest, TestPolymorphicYsonStructDefault) { TMyPolyDefault poly; + auto empty = BuildYsonNodeFluently() + .BeginMap() + .EndMap(); + + Deserialize(poly, empty->AsMap()); + EXPECT_EQ(poly.GetCurrentType(), EMyPolyDefaultType::Drv1); + + auto drv1Ptr = poly.TryGetConcrete<TPolyDerived1>(); + EXPECT_TRUE(drv1Ptr.operator bool()); + + /////////////// + auto node = BuildYsonNodeFluently() .BeginMap() .Item("base_field").Value(11) @@ -3487,11 +3499,13 @@ TEST(TYsonStructTest, TestPolymorphicYsonStructDefault) Deserialize(poly, node->AsMap()); EXPECT_EQ(poly.GetCurrentType(), EMyPolyDefaultType::Drv1); - auto drv1Ptr = poly.TryGetConcrete<TPolyDerived1>(); + drv1Ptr = poly.TryGetConcrete<TPolyDerived1>(); EXPECT_TRUE(drv1Ptr.operator bool()); EXPECT_EQ(drv1Ptr->BaseField, 11); EXPECT_EQ(drv1Ptr->Field1, 123); + /////////////// + node = BuildYsonNodeFluently() .BeginMap() .Item("type").Value("drv2") @@ -3502,6 +3516,8 @@ TEST(TYsonStructTest, TestPolymorphicYsonStructDefault) Deserialize(poly, node->AsMap()); EXPECT_EQ(poly.GetCurrentType(), EMyPolyDefaultType::Drv2); + /////////////// + node = BuildYsonNodeFluently() .BeginMap() .Item("base_field").Value(11) @@ -3528,6 +3544,18 @@ TEST(TYsonStructTest, TestPolymorphicYsonStructDefaultEnum) { TMyPolyDefaultEnum poly; + auto empty = BuildYsonNodeFluently() + .BeginMap() + .EndMap(); + + Deserialize(poly, empty->AsMap()); + + EXPECT_EQ(poly.GetCurrentType(), EMyPolyDefaultEnum::Base); + auto basePtr = poly.TryGetConcrete<TPolyBase>(); + EXPECT_TRUE(basePtr.operator bool()); + + /////////////// + auto node = BuildYsonNodeFluently() .BeginMap() .Item("base_field").Value(11) @@ -3537,10 +3565,12 @@ TEST(TYsonStructTest, TestPolymorphicYsonStructDefaultEnum) Deserialize(poly, node->AsMap()); EXPECT_EQ(poly.GetCurrentType(), EMyPolyDefaultEnum::Base); - auto basePtr = poly.TryGetConcrete<TPolyBase>(); + basePtr = poly.TryGetConcrete<TPolyBase>(); EXPECT_TRUE(basePtr.operator bool()); EXPECT_EQ(basePtr->BaseField, 11); + /////////////// + node = BuildYsonNodeFluently() .BeginMap() .Item("type").Value("drv1") @@ -3551,6 +3581,8 @@ TEST(TYsonStructTest, TestPolymorphicYsonStructDefaultEnum) Deserialize(poly, node->AsMap()); EXPECT_EQ(poly.GetCurrentType(), EMyPolyDefaultEnum::Drv1); + /////////////// + node = BuildYsonNodeFluently() .BeginMap() .Item("base_field").Value(11) @@ -3585,7 +3617,8 @@ TEST(TYsonStructTest, TestPolymorphicYsonStructSerializeEmpty) auto node = ConvertToNode(holder); - Deserialize(holder, node->AsMap()); + // Field `type` is mandatory for structs without configured default type. + EXPECT_THROW(Deserialize(holder, node->AsMap()), std::exception); } TEST(TYsonStructTest, TestPolymorphicYsonStructAsField) |
