aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormaksim-kita <maksim-kita@yandex-team.com>2023-04-27 11:02:58 +0300
committermaksim-kita <maksim-kita@yandex-team.com>2023-04-27 11:02:58 +0300
commitc46268f9104183574c33c78e3407ff245d3968c0 (patch)
tree31c95a88e26dae173b55bd5c5d53e4cd85e54f6a
parent251a1ddd683d582c4168183a875e2ab6b56bd795 (diff)
downloadydb-c46268f9104183574c33c78e3407ff245d3968c0.tar.gz
YDB public API invalid types fix
-rw-r--r--ydb/core/kqp/session_actor/kqp_worker_common.cpp6
-rw-r--r--ydb/core/kqp/ut/query/kqp_query_ut.cpp20
-rw-r--r--ydb/core/ydb_convert/ydb_convert.cpp41
-rw-r--r--ydb/library/mkql_proto/mkql_proto.cpp16
-rw-r--r--ydb/library/mkql_proto/mkql_proto_ut.cpp46
-rw-r--r--ydb/library/mkql_proto/protos/minikql.proto4
-rw-r--r--ydb/library/yql/minikql/mkql_program_builder.cpp8
-rw-r--r--ydb/library/yql/minikql/mkql_program_builder.h2
-rw-r--r--ydb/public/lib/json_value/ydb_json_value.cpp30
-rw-r--r--ydb/public/lib/yson_value/ydb_yson_value.cpp10
10 files changed, 173 insertions, 10 deletions
diff --git a/ydb/core/kqp/session_actor/kqp_worker_common.cpp b/ydb/core/kqp/session_actor/kqp_worker_common.cpp
index 23e204005fa..b57d707f13d 100644
--- a/ydb/core/kqp/session_actor/kqp_worker_common.cpp
+++ b/ydb/core/kqp/session_actor/kqp_worker_common.cpp
@@ -145,12 +145,16 @@ bool IsSameProtoType(const NKikimrMiniKQL::TType& actual, const NKikimrMiniKQL::
return IsSameProtoTypeImpl(actual.GetData(), expected.GetData());
case NKikimrMiniKQL::ETypeKind::Optional:
return IsSameProtoType(actual.GetOptional().GetItem(), expected.GetOptional().GetItem());
+ case NKikimrMiniKQL::ETypeKind::EmptyList:
+ return true;
case NKikimrMiniKQL::ETypeKind::List:
return IsSameProtoType(actual.GetList().GetItem(), expected.GetList().GetItem());
case NKikimrMiniKQL::ETypeKind::Tuple:
return IsSameProtoTypeImpl(actual.GetTuple(), expected.GetTuple());
case NKikimrMiniKQL::ETypeKind::Struct:
return IsSameProtoTypeImpl(actual.GetStruct(), expected.GetStruct());
+ case NKikimrMiniKQL::ETypeKind::EmptyDict:
+ return true;
case NKikimrMiniKQL::ETypeKind::Dict:
return IsSameProtoType(actual.GetDict().GetKey(), expected.GetDict().GetKey()) &&
IsSameProtoType(actual.GetDict().GetPayload(), expected.GetDict().GetPayload());
@@ -164,8 +168,6 @@ bool IsSameProtoType(const NKikimrMiniKQL::TType& actual, const NKikimrMiniKQL::
return (actual.GetTagged().GetTag() == expected.GetTagged().GetTag()) &&
IsSameProtoType(actual.GetTagged().GetItem(), expected.GetTagged().GetItem());
case NKikimrMiniKQL::ETypeKind::Unknown:
- case NKikimrMiniKQL::ETypeKind::Reserved_12:
- case NKikimrMiniKQL::ETypeKind::Reserved_13:
case NKikimrMiniKQL::ETypeKind::Reserved_14:
return false;
}
diff --git a/ydb/core/kqp/ut/query/kqp_query_ut.cpp b/ydb/core/kqp/ut/query/kqp_query_ut.cpp
index 636e93a7a18..39dcf24159f 100644
--- a/ydb/core/kqp/ut/query/kqp_query_ut.cpp
+++ b/ydb/core/kqp/ut/query/kqp_query_ut.cpp
@@ -1332,6 +1332,26 @@ Y_UNIT_TEST_SUITE(KqpQuery) {
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
}
+ Y_UNIT_TEST(QuerySpecialTypes) {
+ TKikimrRunner kikimr;
+ auto db = kikimr.GetTableClient();
+ auto session = db.CreateSession().GetValueSync().GetSession();
+
+ auto result = session.ExecuteDataQuery(Q1_(R"(
+ SELECT null;
+ )"), TTxControl::BeginTx().CommitTx()).ExtractValueSync();
+ UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
+
+ result = session.ExecuteDataQuery(Q1_(R"(
+ SELECT [];
+ )"), TTxControl::BeginTx().CommitTx()).ExtractValueSync();
+ UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
+
+ result = session.ExecuteDataQuery(Q1_(R"(
+ SELECT {};
+ )"), TTxControl::BeginTx().CommitTx()).ExtractValueSync();
+ UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
+ }
}
} // namespace NKqp
diff --git a/ydb/core/ydb_convert/ydb_convert.cpp b/ydb/core/ydb_convert/ydb_convert.cpp
index e73475c1c0e..756ea0afa20 100644
--- a/ydb/core/ydb_convert/ydb_convert.cpp
+++ b/ydb/core/ydb_convert/ydb_convert.cpp
@@ -93,6 +93,10 @@ void ConvertMiniKQLTypeToYdbType(const NKikimrMiniKQL::TType& input, Ydb::Type&
ConvertMiniKQLTypeToYdbType(protoListType.GetItem(), *output.mutable_list_type()->mutable_item());
break;
}
+ case NKikimrMiniKQL::ETypeKind::EmptyList: {
+ output.set_empty_list_type(::google::protobuf::NULL_VALUE);
+ break;
+ }
case NKikimrMiniKQL::ETypeKind::Tuple: {
const NKikimrMiniKQL::TTupleType& protoTupleType = input.GetTuple();
ConvertMiniKQLTupleTypeToYdbType(protoTupleType, *output.mutable_tuple_type());
@@ -109,6 +113,10 @@ void ConvertMiniKQLTypeToYdbType(const NKikimrMiniKQL::TType& input, Ydb::Type&
ConvertMiniKQLTypeToYdbType(protoDictType.GetPayload(), *output.mutable_dict_type()->mutable_payload());
break;
}
+ case NKikimrMiniKQL::ETypeKind::EmptyDict: {
+ output.set_empty_dict_type(::google::protobuf::NULL_VALUE);
+ break;
+ }
case NKikimrMiniKQL::ETypeKind::Variant: {
const NKikimrMiniKQL::TVariantType& protoVariantType = input.GetVariant();
auto variantOut = output.mutable_variant_type();
@@ -143,16 +151,19 @@ void ConvertMiniKQLTypeToYdbType(const NKikimrMiniKQL::TType& input, Ydb::Type&
void ConvertYdbTypeToMiniKQLType(const Ydb::Type& input, NKikimrMiniKQL::TType& output) {
switch (input.type_case()) {
- case Ydb::Type::kVoidType:
+ case Ydb::Type::kVoidType: {
output.SetKind(NKikimrMiniKQL::ETypeKind::Void);
break;
- case Ydb::Type::kNullType:
+ }
+ case Ydb::Type::kNullType: {
output.SetKind(NKikimrMiniKQL::ETypeKind::Null);
break;
- case Ydb::Type::kTypeId:
+ }
+ case Ydb::Type::kTypeId: {
output.SetKind(NKikimrMiniKQL::ETypeKind::Data);
output.MutableData()->SetScheme(input.type_id());
break;
+ }
case Ydb::Type::kDecimalType: {
// TODO: Decimal parameters
output.SetKind(NKikimrMiniKQL::ETypeKind::Data);
@@ -162,14 +173,20 @@ void ConvertYdbTypeToMiniKQLType(const Ydb::Type& input, NKikimrMiniKQL::TType&
data->MutableDecimalParams()->SetScale(input.decimal_type().scale());
break;
}
- case Ydb::Type::kOptionalType:
+ case Ydb::Type::kOptionalType: {
output.SetKind(NKikimrMiniKQL::ETypeKind::Optional);
ConvertYdbTypeToMiniKQLType(input.optional_type().item(), *output.MutableOptional()->MutableItem());
break;
- case Ydb::Type::kListType:
+ }
+ case Ydb::Type::kListType: {
output.SetKind(NKikimrMiniKQL::ETypeKind::List);
ConvertYdbTypeToMiniKQLType(input.list_type().item(), *output.MutableList()->MutableItem());
break;
+ }
+ case Ydb::Type::kEmptyListType: {
+ output.SetKind(NKikimrMiniKQL::ETypeKind::EmptyList);
+ break;
+ }
case Ydb::Type::kTupleType: {
output.SetKind(NKikimrMiniKQL::ETypeKind::Tuple);
const Ydb::TupleType& protoTupleType = input.tuple_type();
@@ -189,6 +206,10 @@ void ConvertYdbTypeToMiniKQLType(const Ydb::Type& input, NKikimrMiniKQL::TType&
ConvertYdbTypeToMiniKQLType(protoDictType.payload(), *output.MutableDict()->MutablePayload());
break;
}
+ case Ydb::Type::kEmptyDictType: {
+ output.SetKind(NKikimrMiniKQL::ETypeKind::EmptyDict);
+ break;
+ }
case Ydb::Type::kVariantType: {
output.SetKind(NKikimrMiniKQL::ETypeKind::Variant);
const Ydb::VariantType& protoVariantType = input.variant_type();
@@ -470,6 +491,12 @@ void ConvertMiniKQLValueToYdbValue(const NKikimrMiniKQL::TType& inputType,
case NKikimrMiniKQL::ETypeKind::Void: {
break;
}
+ case NKikimrMiniKQL::ETypeKind::EmptyList: {
+ break;
+ }
+ case NKikimrMiniKQL::ETypeKind::EmptyDict: {
+ break;
+ }
case NKikimrMiniKQL::ETypeKind::Null: {
output.set_null_flag_value(::google::protobuf::NULL_VALUE);
break;
@@ -603,6 +630,10 @@ void ConvertYdbValueToMiniKQLValue(const Ydb::Type& inputType,
switch (inputType.type_case()) {
case Ydb::Type::kVoidType:
break;
+ case Ydb::Type::kEmptyListType:
+ break;
+ case Ydb::Type::kEmptyDictType:
+ break;
case Ydb::Type::kTypeId:
ConvertData(inputType.type_id(), inputValue, output);
break;
diff --git a/ydb/library/mkql_proto/mkql_proto.cpp b/ydb/library/mkql_proto/mkql_proto.cpp
index b95cb6feea2..112a14b5751 100644
--- a/ydb/library/mkql_proto/mkql_proto.cpp
+++ b/ydb/library/mkql_proto/mkql_proto.cpp
@@ -178,6 +178,11 @@ void ExportTypeToProtoImpl(TType* type, NKikimrMiniKQL::TType& res, const TVecto
break;
}
+ case TType::EKind::EmptyList: {
+ res.SetKind(NKikimrMiniKQL::ETypeKind::EmptyList);
+ break;
+ }
+
case TType::EKind::List: {
auto listType = static_cast<TListType *>(type);
res.SetKind(NKikimrMiniKQL::ETypeKind::List);
@@ -203,6 +208,11 @@ void ExportTypeToProtoImpl(TType* type, NKikimrMiniKQL::TType& res, const TVecto
break;
}
+ case TType::EKind::EmptyDict: {
+ res.SetKind(NKikimrMiniKQL::ETypeKind::EmptyDict);
+ break;
+ }
+
case TType::EKind::Dict: {
auto dictType = static_cast<TDictType *>(type);
res.SetKind(NKikimrMiniKQL::ETypeKind::Dict);
@@ -1034,6 +1044,9 @@ TType* TProtoImporter::ImportTypeFromProto(const NKikimrMiniKQL::TType& type) {
TType* child = ImportTypeFromProto(protoTaggedType.GetItem());
return TTaggedType::Create(child, protoTaggedType.GetTag(), env);
}
+ case NKikimrMiniKQL::ETypeKind::EmptyList: {
+ return env.GetTypeOfEmptyList();
+ }
case NKikimrMiniKQL::ETypeKind::List: {
const NKikimrMiniKQL::TListType& protoListType = type.GetList();
const NKikimrMiniKQL::TType& protoItemType = protoListType.GetItem();
@@ -1049,6 +1062,9 @@ TType* TProtoImporter::ImportTypeFromProto(const NKikimrMiniKQL::TType& type) {
const NKikimrMiniKQL::TStructType& protoStructType = type.GetStruct();
return ImportStructTypeFromProto(protoStructType);
}
+ case NKikimrMiniKQL::ETypeKind::EmptyDict: {
+ return env.GetTypeOfEmptyDict();
+ }
case NKikimrMiniKQL::ETypeKind::Dict: {
const NKikimrMiniKQL::TDictType& protoDictType = type.GetDict();
diff --git a/ydb/library/mkql_proto/mkql_proto_ut.cpp b/ydb/library/mkql_proto/mkql_proto_ut.cpp
index 2337519db65..5892dbb6e79 100644
--- a/ydb/library/mkql_proto/mkql_proto_ut.cpp
+++ b/ydb/library/mkql_proto/mkql_proto_ut.cpp
@@ -35,6 +35,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLProtoTest) {
}, "Kind: Void\n");
}
+ Y_UNIT_TEST(TestExportNullType) {
+ TestExportType<NKikimrMiniKQL::TType>([](TProgramBuilder &pgmBuilder) {
+ auto pgmReturn = pgmBuilder.NewNull();
+ return pgmReturn;
+ }, "Kind: Null\n");
+ }
+
Y_UNIT_TEST(TestExportDataType) {
TestExportType<NKikimrMiniKQL::TType>([](TProgramBuilder& pgmBuilder) {
auto pgmReturn = pgmBuilder.NewDataLiteral<i32>(42);
@@ -142,6 +149,14 @@ Y_UNIT_TEST_SUITE(TMiniKQLProtoTest) {
"}\n");
}
+ Y_UNIT_TEST(TestExportEmptyListType) {
+ TestExportType<NKikimrMiniKQL::TType>([](TProgramBuilder& pgmBuilder) {
+ auto pgmReturn = pgmBuilder.NewEmptyList();
+ return pgmReturn;
+ },
+ "Kind: EmptyList\n");
+ }
+
Y_UNIT_TEST(TestExportListType) {
TestExportType<NKikimrMiniKQL::TType>([](TProgramBuilder& pgmBuilder) {
auto pgmReturn = pgmBuilder.AsList(pgmBuilder.NewDataLiteral<i32>(42));
@@ -248,6 +263,14 @@ Y_UNIT_TEST_SUITE(TMiniKQLProtoTest) {
"}\n");
}
+ Y_UNIT_TEST(TestExportEmptyDictType) {
+ TestExportType<NKikimrMiniKQL::TType>([](TProgramBuilder& pgmBuilder) {
+ auto pgmReturn = pgmBuilder.NewEmptyDict();
+ return pgmReturn;
+ },
+ "Kind: EmptyDict\n");
+ }
+
Y_UNIT_TEST(TestExportDictType) {
TestExportType<NKikimrMiniKQL::TType>([](TProgramBuilder& pgmBuilder) {
auto dictType = pgmBuilder.NewDictType(pgmBuilder.NewDataType(NUdf::TDataType<i32>::Id),
@@ -484,6 +507,13 @@ Variant {
"Hi128: 18441323062847124093\n");
}
+ Y_UNIT_TEST(TestExportNull) {
+ TestExportValue<NKikimrMiniKQL::TValue>([](TProgramBuilder& pgmBuilder) {
+ auto pgmReturn = pgmBuilder.NewNull();
+ return pgmReturn;
+ }, "NullFlagValue: NULL_VALUE\n");
+ }
+
Y_UNIT_TEST(TestExportEmptyOptional) {
TestExportValue<NKikimrMiniKQL::TValue>([](TProgramBuilder& pgmBuilder) {
auto pgmReturn = pgmBuilder.NewEmptyOptionalDataLiteral(NUdf::TDataType<char*>::Id);
@@ -511,6 +541,14 @@ Variant {
"}\n");
}
+ Y_UNIT_TEST(TestExportEmptyList) {
+ TestExportValue<NKikimrMiniKQL::TValue>([](TProgramBuilder& pgmBuilder) {
+ auto pgmReturn = pgmBuilder.NewEmptyList();
+ return pgmReturn;
+ },
+ "");
+ }
+
Y_UNIT_TEST(TestExportList) {
TestExportValue<NKikimrMiniKQL::TValue>([](TProgramBuilder& pgmBuilder) {
auto pgmReturn = pgmBuilder.AsList(pgmBuilder.NewDataLiteral<NUdf::EDataSlot::String>("abc"));
@@ -618,6 +656,14 @@ Variant {
&columnOrder);
}
+ Y_UNIT_TEST(TestExportEmptyDict) {
+ TestExportValue<NKikimrMiniKQL::TValue>([](TProgramBuilder& pgmBuilder) {
+ auto pgmReturn = pgmBuilder.NewEmptyDict();
+ return pgmReturn;
+ },
+ "");
+ }
+
Y_UNIT_TEST(TestExportDict) {
TestExportValue<NKikimrMiniKQL::TValue>([](TProgramBuilder& pgmBuilder) {
auto dictType = pgmBuilder.NewDictType(pgmBuilder.NewDataType(NUdf::TDataType<i32>::Id),
diff --git a/ydb/library/mkql_proto/protos/minikql.proto b/ydb/library/mkql_proto/protos/minikql.proto
index 444efdef8a2..25343921675 100644
--- a/ydb/library/mkql_proto/protos/minikql.proto
+++ b/ydb/library/mkql_proto/protos/minikql.proto
@@ -17,8 +17,8 @@ enum ETypeKind {
Null = 9;
Pg = 10;
Tagged = 11;
- Reserved_12 = 12;
- Reserved_13 = 13;
+ EmptyList = 12;
+ EmptyDict = 13;
Reserved_14 = 14;
}
diff --git a/ydb/library/yql/minikql/mkql_program_builder.cpp b/ydb/library/yql/minikql/mkql_program_builder.cpp
index 84a9071c86a..9bb8cc0ceac 100644
--- a/ydb/library/yql/minikql/mkql_program_builder.cpp
+++ b/ydb/library/yql/minikql/mkql_program_builder.cpp
@@ -2257,6 +2257,10 @@ TRuntimeNode TProgramBuilder::NewStruct(TType* structType, const TArrayRef<const
return TRuntimeNode(TStructLiteral::Create(values.size(), values.data(), detailedStructType, Env), true);
}
+TRuntimeNode TProgramBuilder::NewEmptyList() {
+ return TRuntimeNode(Env.GetEmptyList(), true);
+}
+
TRuntimeNode TProgramBuilder::NewEmptyList(TType* itemType) {
TListLiteralBuilder builder(Env, itemType);
return TRuntimeNode(builder.Build(), true);
@@ -2311,6 +2315,10 @@ TType* TProgramBuilder::NewDictType(TType* keyType, TType* payloadType, bool mul
return TDictType::Create(keyType, multi ? NewListType(payloadType) : payloadType, Env);
}
+TRuntimeNode TProgramBuilder::NewEmptyDict() {
+ return TRuntimeNode(Env.GetEmptyDict(), true);
+}
+
TRuntimeNode TProgramBuilder::NewDict(TType* dictType, const TArrayRef<const std::pair<TRuntimeNode, TRuntimeNode>>& items) {
MKQL_ENSURE(dictType->IsDict(), "Expected dict type");
diff --git a/ydb/library/yql/minikql/mkql_program_builder.h b/ydb/library/yql/minikql/mkql_program_builder.h
index a54bcf14b91..815af9df4f9 100644
--- a/ydb/library/yql/minikql/mkql_program_builder.h
+++ b/ydb/library/yql/minikql/mkql_program_builder.h
@@ -176,11 +176,13 @@ public:
TRuntimeNode NewStruct(TType* structType, const TArrayRef<const std::pair<std::string_view, TRuntimeNode>>& members);
TType* NewListType(TType* itemType);
+ TRuntimeNode NewEmptyList();
TRuntimeNode NewEmptyList(TType* itemType);
TRuntimeNode NewEmptyListOfVoid();
TRuntimeNode NewList(TType* itemType, const TArrayRef<const TRuntimeNode>& items);
TType* NewDictType(TType* keyType, TType* payloadType, bool multi);
+ TRuntimeNode NewEmptyDict();
TRuntimeNode NewDict(TType* dictType, const TArrayRef<const std::pair<TRuntimeNode, TRuntimeNode>>& items);
TType* NewStreamType(TType* itemType);
diff --git a/ydb/public/lib/json_value/ydb_json_value.cpp b/ydb/public/lib/json_value/ydb_json_value.cpp
index ffda0cc0189..d247f4a5a96 100644
--- a/ydb/public/lib/json_value/ydb_json_value.cpp
+++ b/ydb/public/lib/json_value/ydb_json_value.cpp
@@ -241,6 +241,13 @@ namespace NYdb {
Parser.CloseTagged();
break;
+ case TTypeParser::ETypeKind::EmptyList:
+ {
+ Writer.BeginList();
+ Writer.EndList();
+ break;
+ }
+
case TTypeParser::ETypeKind::List:
Parser.OpenList();
Writer.BeginList();
@@ -278,6 +285,13 @@ namespace NYdb {
Writer.EndList();
break;
+ case TTypeParser::ETypeKind::EmptyDict:
+ {
+ Writer.BeginList();
+ Writer.EndList();
+ break;
+ }
+
case TTypeParser::ETypeKind::Dict:
Parser.OpenDict();
Writer.BeginList();
@@ -293,7 +307,9 @@ namespace NYdb {
Parser.CloseDict();
Writer.EndList();
break;
-
+ case TTypeParser::ETypeKind::Null:
+ Writer.WriteNull();
+ break;
default:
ThrowFatalError(TStringBuilder() << "Unsupported type kind: " << Parser.GetKind());
}
@@ -648,6 +664,10 @@ namespace {
void ParseValue(const NJson::TJsonValue& jsonValue) {
switch (TypeParser.GetKind()) {
+ case TTypeParser::ETypeKind::Null:
+ EnsureType(jsonValue, NJson::JSON_NULL);
+ break;
+
case TTypeParser::ETypeKind::Primitive:
ParsePrimitiveValue(jsonValue, TypeParser.GetPrimitive());
break;
@@ -696,6 +716,10 @@ namespace {
TypeParser.CloseTagged();
break;
+ case TTypeParser::ETypeKind::EmptyList:
+ EnsureType(jsonValue, NJson::JSON_ARRAY);
+ break;
+
case TTypeParser::ETypeKind::List:
EnsureType(jsonValue, NJson::JSON_ARRAY);
TypeParser.OpenList();
@@ -753,6 +777,10 @@ namespace {
TypeParser.CloseTuple();
break;
+ case TTypeParser::ETypeKind::EmptyDict:
+ EnsureType(jsonValue, NJson::JSON_ARRAY);
+ break;
+
case TTypeParser::ETypeKind::Dict:
EnsureType(jsonValue, NJson::JSON_ARRAY);
TypeParser.OpenDict();
diff --git a/ydb/public/lib/yson_value/ydb_yson_value.cpp b/ydb/public/lib/yson_value/ydb_yson_value.cpp
index 8f04fa67489..2734f4962a8 100644
--- a/ydb/public/lib/yson_value/ydb_yson_value.cpp
+++ b/ydb/public/lib/yson_value/ydb_yson_value.cpp
@@ -133,6 +133,11 @@ static void FormatValueYsonInternal(TValueParser& parser, NYson::TYsonWriter& wr
parser.CloseTagged();
break;
+ case TTypeParser::ETypeKind::EmptyList:
+ writer.OnBeginList();
+ writer.OnEndList();
+ break;
+
case TTypeParser::ETypeKind::List:
parser.OpenList();
writer.OnBeginList();
@@ -172,6 +177,11 @@ static void FormatValueYsonInternal(TValueParser& parser, NYson::TYsonWriter& wr
parser.CloseTuple();
break;
+ case TTypeParser::ETypeKind::EmptyDict:
+ writer.OnBeginList();
+ writer.OnEndList();
+ break;
+
case TTypeParser::ETypeKind::Dict:
parser.OpenDict();
writer.OnBeginList();