diff options
| author | uzhas <[email protected]> | 2022-12-05 18:11:18 +0300 |
|---|---|---|
| committer | uzhas <[email protected]> | 2022-12-05 18:11:18 +0300 |
| commit | d4195ed627058ff09181afee4edf6e9b7d7bf5dd (patch) | |
| tree | ffa3ae124508548435218be8e11f48fa10ee8f87 | |
| parent | 2bcafecb6458e7aa1ae930599f061cc01e3ba59b (diff) | |
suport Tagged type in Ydb::Value and Ydb::Type builders, yson/json formatter and parser
8 files changed, 173 insertions, 1 deletions
diff --git a/ydb/public/lib/json_value/ydb_json_value.cpp b/ydb/public/lib/json_value/ydb_json_value.cpp index dbfb05b315e..50f2ea3f5b3 100644 --- a/ydb/public/lib/json_value/ydb_json_value.cpp +++ b/ydb/public/lib/json_value/ydb_json_value.cpp @@ -235,6 +235,12 @@ namespace NYdb { Parser.CloseOptional(); break; + case TTypeParser::ETypeKind::Tagged: + Parser.OpenTagged(); + ParseValue(); + Parser.CloseTagged(); + break; + case TTypeParser::ETypeKind::List: Parser.OpenList(); Writer.BeginList(); @@ -652,7 +658,7 @@ namespace { break; case TTypeParser::ETypeKind::Pg: { - TPgType pgType(0, 0, 0); + TPgType pgType(0, -1, -1); if (jsonValue.GetType() == NJson::JSON_STRING) { ValueBuilder.Pg(TPgValue(TPgValue::VK_TEXT, jsonValue.GetString(), pgType)); } else if (jsonValue.GetType() == NJson::JSON_NULL) { @@ -682,6 +688,14 @@ namespace { TypeParser.CloseOptional(); break; + case TTypeParser::ETypeKind::Tagged: + TypeParser.OpenTagged(); + ValueBuilder.BeginTagged(TypeParser.GetTag()); + ParseValue(jsonValue); + ValueBuilder.EndTagged(); + TypeParser.CloseTagged(); + break; + case TTypeParser::ETypeKind::List: EnsureType(jsonValue, NJson::JSON_ARRAY); TypeParser.OpenList(); diff --git a/ydb/public/lib/json_value/ydb_json_value_ut.cpp b/ydb/public/lib/json_value/ydb_json_value_ut.cpp index afa9584225d..0856192673d 100644 --- a/ydb/public/lib/json_value/ydb_json_value_ut.cpp +++ b/ydb/public/lib/json_value/ydb_json_value_ut.cpp @@ -441,6 +441,23 @@ Y_UNIT_TEST_SUITE(JsonValueTest) { ); } + Y_UNIT_TEST(TaggedValue) { + TValue value = TValueBuilder() + .BeginTagged("my_tag") + .BeginTagged("my_inner_tag") + .Uint32(1) + .EndTagged() + .EndTagged() + .Build(); + const TString jsonString = FormatValueJson(value, EBinaryStringEncoding::Unicode); + UNIT_ASSERT_NO_DIFF(jsonString, R"(1)"); + TValue resultValue = JsonToYdbValue(jsonString, value.GetType(), EBinaryStringEncoding::Unicode); + UNIT_ASSERT_NO_DIFF( + TProtoAccessor::GetProto(value).DebugString(), + TProtoAccessor::GetProto(resultValue).DebugString() + ); + } + Y_UNIT_TEST(CompositeValueEmptyList) { TValue value = TValueBuilder() .EmptyList(TTypeBuilder().Primitive(EPrimitiveType::Uint32).Build()) diff --git a/ydb/public/lib/yson_value/ydb_yson_value.cpp b/ydb/public/lib/yson_value/ydb_yson_value.cpp index 5658f1edbd5..8f04fa67489 100644 --- a/ydb/public/lib/yson_value/ydb_yson_value.cpp +++ b/ydb/public/lib/yson_value/ydb_yson_value.cpp @@ -127,6 +127,12 @@ static void FormatValueYsonInternal(TValueParser& parser, NYson::TYsonWriter& wr parser.CloseOptional(); break; + case TTypeParser::ETypeKind::Tagged: + parser.OpenTagged(); + FormatValueYsonInternal(parser, writer); + parser.CloseTagged(); + break; + case TTypeParser::ETypeKind::List: parser.OpenList(); writer.OnBeginList(); diff --git a/ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/CMakeLists.txt b/ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/CMakeLists.txt index 060b00dfdf4..746159a98bb 100644 --- a/ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/CMakeLists.txt +++ b/ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(impl-ydb_internal-value_helpers PUBLIC contrib-libs-cxxsupp yutil api-protos + client-ydb_types-fatal_error_handlers ) target_sources(impl-ydb_internal-value_helpers PRIVATE ${CMAKE_SOURCE_DIR}/ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/helpers.cpp diff --git a/ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/helpers.cpp b/ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/helpers.cpp index e87ec8af1e5..d2eff31232e 100644 --- a/ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/helpers.cpp +++ b/ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/helpers.cpp @@ -1,5 +1,7 @@ #define INCLUDE_YDB_INTERNAL_H #include "helpers.h" +#include <ydb/public/sdk/cpp/client/ydb_types/fatal_error_handlers/handlers.h> +#include <util/string/builder.h> namespace NYdb { @@ -20,6 +22,9 @@ bool TypesEqual(const Ydb::Type& t1, const Ydb::Type& t2) { && t1.pg_type().typmod() == t2.pg_type().typmod(); case Ydb::Type::kOptionalType: return TypesEqual(t1.optional_type().item(), t2.optional_type().item()); + case Ydb::Type::kTaggedType: + return t1.tagged_type().tag() == t2.tagged_type().tag() && + TypesEqual(t1.tagged_type().type(), t2.tagged_type().type()); case Ydb::Type::kListType: return TypesEqual(t1.list_type().item(), t2.list_type().item()); case Ydb::Type::kTupleType: @@ -85,13 +90,21 @@ bool TypesEqual(const Ydb::Type& t1, const Ydb::Type& t2) { } return true; default: + ThrowFatalError(TStringBuilder() << "Unexpected Variant type case " << static_cast<int>(t1.type_case())); return false; } return false; } case Ydb::Type::kVoidType: return true; + case Ydb::Type::kNullType: + return true; + case Ydb::Type::kEmptyListType: + return true; + case Ydb::Type::kEmptyDictType: + return true; default: + ThrowFatalError(TStringBuilder() << "Unexpected type case " << static_cast<int>(t1.type_case())); return false; } } diff --git a/ydb/public/sdk/cpp/client/ydb_value/value.cpp b/ydb/public/sdk/cpp/client/ydb_value/value.cpp index c9c9a7edd59..71c69959c69 100644 --- a/ydb/public/sdk/cpp/client/ydb_value/value.cpp +++ b/ydb/public/sdk/cpp/client/ydb_value/value.cpp @@ -483,6 +483,14 @@ void FormatTypeInternal(TTypeParser& parser, IOutputStream& out) { out << '?'; break; + case TTypeParser::ETypeKind::Tagged: + parser.OpenTagged(); + out << "Tagged<"; + FormatTypeInternal(parser, out); + out << ",\'" << parser.GetTag() << "\'>"; + parser.CloseTagged(); + break; + case TTypeParser::ETypeKind::List: out << "List<"; parser.OpenList(); @@ -710,6 +718,21 @@ public: GetProto().CopyFrom(TProtoAccessor::GetProto(payloadType)); } + void BeginTagged(const TString& tag) { + GetProto().mutable_tagged_type()->set_tag(tag); + AddPosition(GetProto().mutable_tagged_type()->mutable_type()); + } + + void EndTagged() { + CloseContainer<ETypeKind::Tagged>(); + } + + void Tagged(const TString& tag, const TType& itemType) { + auto taggedType = GetProto().mutable_tagged_type(); + taggedType->set_tag(tag); + taggedType->mutable_type()->CopyFrom(TProtoAccessor::GetProto(itemType)); + } + Ydb::Type& GetProto(ui32 offset = 0) { return *static_cast<Ydb::Type*>(Path_[Path_.size() - (offset + 1)].Ptr); } @@ -891,6 +914,21 @@ TTypeBuilder& TTypeBuilder::EndDict() { return *this; } +TTypeBuilder& TTypeBuilder::BeginTagged(const TString& tag) { + Impl_->BeginTagged(tag); + return *this; +} + +TTypeBuilder& TTypeBuilder::EndTagged() { + Impl_->EndTagged(); + return *this; +} + +TTypeBuilder& TTypeBuilder::Tagged(const TString& tag, const TType& itemType) { + Impl_->Tagged(tag, itemType); + return *this; +} + //////////////////////////////////////////////////////////////////////////////// TDecimalValue::TDecimalValue(const Ydb::Value& valueProto, const TDecimalType& decimalType) @@ -1341,6 +1379,10 @@ private: } void PopPath() { + if (Path_.empty()) { + FatalError(TStringBuilder() << "Bad parser state, no open value."); + } + Path_.pop_back(); } @@ -2420,6 +2462,19 @@ public: EndDict(); } + void BeginTagged(const TString& tag) { + SetBuildType(!CheckType(ETypeKind::Tagged)); + TypeBuilder_.BeginTagged(tag); + PushPath(GetValue()); + } + + void EndTagged() { + CheckContainerKind(ETypeKind::Tagged); + + PopPath(); + TypeBuilder_.EndTagged(); + } + private: Ydb::Type& GetType(size_t offset = 0) { return TypeBuilder_.GetProto(offset); @@ -3094,6 +3149,18 @@ TDerived& TValueBuilderBase<TDerived>::EmptyDict() { return static_cast<TDerived&>(*this); } +template<typename TDerived> +TDerived& TValueBuilderBase<TDerived>::BeginTagged(const TString& tag) { + Impl_->BeginTagged(tag); + return static_cast<TDerived&>(*this); +} + +template<typename TDerived> +TDerived& TValueBuilderBase<TDerived>::EndTagged() { + Impl_->EndTagged(); + return static_cast<TDerived&>(*this); +} + //////////////////////////////////////////////////////////////////////////////// template class TValueBuilderBase<TValueBuilder>; diff --git a/ydb/public/sdk/cpp/client/ydb_value/value.h b/ydb/public/sdk/cpp/client/ydb_value/value.h index 0186260a984..5c7c885daa7 100644 --- a/ydb/public/sdk/cpp/client/ydb_value/value.h +++ b/ydb/public/sdk/cpp/client/ydb_value/value.h @@ -203,6 +203,11 @@ public: TTypeBuilder& DictPayload(const TType& payloadType); TTypeBuilder& EndDict(); + // Tagged + TTypeBuilder& BeginTagged(const TString& tag); + TTypeBuilder& EndTagged(); + TTypeBuilder& Tagged(const TString& tag, const TType& itemType); + TType Build(); private: @@ -475,6 +480,10 @@ public: TDerived& EmptyDict(const TType& keyType, const TType& payloadType); TDerived& EmptyDict(); + // Tagged + TDerived& BeginTagged(const TString& tag); + TDerived& EndTagged(); + protected: TValueBuilderBase(TValueBuilderBase&&); diff --git a/ydb/public/sdk/cpp/client/ydb_value/value_ut.cpp b/ydb/public/sdk/cpp/client/ydb_value/value_ut.cpp index 43c23dbbd69..78f6ca72a2f 100644 --- a/ydb/public/sdk/cpp/client/ydb_value/value_ut.cpp +++ b/ydb/public/sdk/cpp/client/ydb_value/value_ut.cpp @@ -93,6 +93,38 @@ Y_UNIT_TEST_SUITE(YdbValue) { R"(Dict<Uint32,Struct<'Member1':Date>>)"); } + Y_UNIT_TEST(ParseTaggedType) { + auto protoTypeStr = R"( + tagged_type { + tag: "my_tag" + type { + type_id: STRING + } + } + )"; + + Ydb::Type protoType; + NProtoBuf::TextFormat::ParseFromString(protoTypeStr, &protoType); + + UNIT_ASSERT_NO_DIFF(FormatType(protoType), + R"(Tagged<String,'my_tag'>)"); + } + + Y_UNIT_TEST(BuildTaggedType) { + auto type = TTypeBuilder() + .BeginTagged("my_tag") + .BeginList() + .BeginOptional() + .Primitive(EPrimitiveType::Uint32) + .EndOptional() + .EndList() + .EndTagged() + .Build(); + + UNIT_ASSERT_NO_DIFF(FormatType(type), + R"(Tagged<List<Uint32?>,'my_tag'>)"); + } + Y_UNIT_TEST(BuildType) { auto type = TTypeBuilder() .BeginStruct() @@ -614,6 +646,19 @@ Y_UNIT_TEST_SUITE(YdbValue) { R"("12.345")"); } + Y_UNIT_TEST(BuildTaggedValue) { + auto value = TValueBuilder() + .BeginTagged("my_tag") + .DyNumber("12.345") + .EndTagged() + .Build(); + + UNIT_ASSERT_NO_DIFF(FormatValueYson(value), + R"("12.345")"); + UNIT_ASSERT_NO_DIFF(FormatValueJson(value, EBinaryStringEncoding::Unicode), + R"("12.345")"); + } + Y_UNIT_TEST(BuildValueList) { auto intValue = TValueBuilder() .Int32(21) |
