diff options
author | Egor Chunaev <egor.chunaev@pinely.com> | 2023-11-23 18:08:40 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2023-11-23 18:36:56 +0300 |
commit | 1c6a0f0555dad6bcacf5ef2614d7cd88627609f0 (patch) | |
tree | f953529aff78e88ec7be727345e0a50bc457d849 | |
parent | 50c69e8394f3c3e1afef75878953a4c4691d4383 (diff) | |
download | ydb-1c6a0f0555dad6bcacf5ef2614d7cd88627609f0.tar.gz |
Fix serialization of decimal type in TTableSchema
I hereby agree to the terms of the CLA available at: https://yandex.ru/legal/cla/?lang=en
Fix for https://github.com/ytsaurus/ytsaurus/issues/173
---
Pull Request resolved: https://github.com/ytsaurus/ytsaurus/pull/174
Co-authored-by: ermolovd <ermolovd@yandex-team.com>
-rw-r--r-- | yt/cpp/mapreduce/client/skiff.cpp | 10 | ||||
-rw-r--r-- | yt/cpp/mapreduce/interface/common_ut.cpp | 44 | ||||
-rw-r--r-- | yt/cpp/mapreduce/interface/serialize.cpp | 10 |
3 files changed, 60 insertions, 4 deletions
diff --git a/yt/cpp/mapreduce/client/skiff.cpp b/yt/cpp/mapreduce/client/skiff.cpp index ab133e1ae3..1eb2e80d79 100644 --- a/yt/cpp/mapreduce/client/skiff.cpp +++ b/yt/cpp/mapreduce/client/skiff.cpp @@ -108,12 +108,18 @@ NSkiff::TSkiffSchemaPtr CreateSkiffSchema( TVector<TSkiffSchemaPtr> skiffColumns; for (const auto& column: schema.Columns()) { TSkiffSchemaPtr skiffColumn; + if (column.Deleted().Defined() && *column.Deleted()) { + continue; + } if (column.Type() == VT_ANY && *column.TypeV3() != *NTi::Optional(NTi::Yson())) { // We ignore all complex types until YT-12717 is done. return nullptr; } - if (column.Deleted().Defined() && *column.Deleted()) { - continue; + if (column.TypeV3()->IsDecimal() || + column.TypeV3()->IsOptional() && column.TypeV3()->AsOptional()->GetItemType()->IsDecimal()) + { + // Complex logic for decimal types, ignore them for now. + return nullptr; } if (column.Required() || NTi::IsSingular(column.TypeV3()->GetTypeName())) { skiffColumn = CreateSimpleTypeSchema(ValueTypeToSkiffType(column.Type())); diff --git a/yt/cpp/mapreduce/interface/common_ut.cpp b/yt/cpp/mapreduce/interface/common_ut.cpp index 3f19433816..f9f0664039 100644 --- a/yt/cpp/mapreduce/interface/common_ut.cpp +++ b/yt/cpp/mapreduce/interface/common_ut.cpp @@ -176,6 +176,45 @@ Y_UNIT_TEST_SUITE(Common) UNIT_ASSERT_EXCEPTION(checkSortBy(schema, {"a", "junk"}), yexception); } + Y_UNIT_TEST(TTableSchema_Decimal) + { + NYT::TTableSchema tableSchema; + + tableSchema.AddColumn("a", NTi::Decimal(35, 18)); + tableSchema.AddColumn("b", NTi::Optional(NTi::Decimal(35, 18))); + tableSchema.AddColumn("c", NTi::List(NTi::Decimal(35, 18))); + + auto tableSchemaNode = tableSchema.ToNode(); + const auto& tableSchemaNodeList = tableSchemaNode.AsList(); + + // There was a bug in the serialization of decimal type: https://github.com/ytsaurus/ytsaurus/issues/173 + { + const auto& currentType = tableSchemaNodeList[0]; + UNIT_ASSERT_VALUES_EQUAL(currentType.ChildAsString("type"), "string"); + UNIT_ASSERT(currentType.ChildAsBool("required")); + UNIT_ASSERT(currentType.HasKey("type_v3")); + UNIT_ASSERT_VALUES_EQUAL(currentType.At("type_v3").ChildAsString("type_name"), "decimal"); + } + { + const auto& currentType = tableSchemaNodeList[1]; + UNIT_ASSERT_VALUES_EQUAL(currentType.ChildAsString("type"), "string"); + UNIT_ASSERT(!currentType.ChildAsBool("required")); + UNIT_ASSERT(currentType.HasKey("type_v3")); + UNIT_ASSERT_VALUES_EQUAL(currentType.At("type_v3").ChildAsString("type_name"), "optional"); + UNIT_ASSERT_VALUES_EQUAL(currentType.At("type_v3").At("item").ChildAsString("type_name"), "decimal"); + } + { + const auto& currentType = tableSchemaNodeList[2]; + UNIT_ASSERT_VALUES_EQUAL(currentType.ChildAsString("type"), "any"); + UNIT_ASSERT(currentType.ChildAsBool("required")); + UNIT_ASSERT(currentType.HasKey("type_v3")); + UNIT_ASSERT_VALUES_EQUAL(currentType.At("type_v3").ChildAsString("type_name"), "list"); + UNIT_ASSERT_VALUES_EQUAL(currentType.At("type_v3").At("item").ChildAsString("type_name"), "decimal"); + } + + UNIT_ASSERT_EQUAL(tableSchema, TTableSchema::FromNode(tableSchemaNode)); + } + Y_UNIT_TEST(TColumnSchema_TypeV3) { { @@ -198,6 +237,11 @@ Y_UNIT_TEST_SUITE(Common) UNIT_ASSERT_VALUES_EQUAL(column.Required(), false); UNIT_ASSERT_VALUES_EQUAL(column.Type(), VT_ANY); } + { + auto column = TColumnSchema().Type(NTi::Decimal(35, 18)); + UNIT_ASSERT_VALUES_EQUAL(column.Required(), true); + UNIT_ASSERT_VALUES_EQUAL(column.Type(), VT_STRING); + } } Y_UNIT_TEST(ToTypeV3) diff --git a/yt/cpp/mapreduce/interface/serialize.cpp b/yt/cpp/mapreduce/interface/serialize.cpp index 7cd8417487..8e701d30b4 100644 --- a/yt/cpp/mapreduce/interface/serialize.cpp +++ b/yt/cpp/mapreduce/interface/serialize.cpp @@ -165,10 +165,16 @@ void Serialize(const TColumnSchema& columnSchema, NYson::IYsonConsumer* consumer .Item("name").Value(columnSchema.Name()) .DoIf(!columnSchema.RawTypeV3().Defined(), [&] (TFluentMap fluent) { + static const auto optionalYson = NTi::Optional(NTi::Yson()); + fluent.Item("type").Value(NDetail::ToString(columnSchema.Type())); fluent.Item("required").Value(columnSchema.Required()); - if (columnSchema.Type() == VT_ANY - && *columnSchema.TypeV3() != *NTi::Optional(NTi::Yson())) + if ( + (columnSchema.Type() == VT_ANY && *columnSchema.TypeV3() != *optionalYson) || + // See https://github.com/ytsaurus/ytsaurus/issues/173 + columnSchema.TypeV3()->IsDecimal() || + (columnSchema.TypeV3()->IsOptional() && columnSchema.TypeV3()->AsOptional()->GetItemType()->IsDecimal())) + { // A lot of user canonize serialized schema. // To be backward compatible we only set type_v3 for new types. |