summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruzhas <[email protected]>2022-12-05 18:11:18 +0300
committeruzhas <[email protected]>2022-12-05 18:11:18 +0300
commitd4195ed627058ff09181afee4edf6e9b7d7bf5dd (patch)
treeffa3ae124508548435218be8e11f48fa10ee8f87
parent2bcafecb6458e7aa1ae930599f061cc01e3ba59b (diff)
suport Tagged type in Ydb::Value and Ydb::Type builders, yson/json formatter and parser
-rw-r--r--ydb/public/lib/json_value/ydb_json_value.cpp16
-rw-r--r--ydb/public/lib/json_value/ydb_json_value_ut.cpp17
-rw-r--r--ydb/public/lib/yson_value/ydb_yson_value.cpp6
-rw-r--r--ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/CMakeLists.txt1
-rw-r--r--ydb/public/sdk/cpp/client/impl/ydb_internal/value_helpers/helpers.cpp13
-rw-r--r--ydb/public/sdk/cpp/client/ydb_value/value.cpp67
-rw-r--r--ydb/public/sdk/cpp/client/ydb_value/value.h9
-rw-r--r--ydb/public/sdk/cpp/client/ydb_value/value_ut.cpp45
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)