aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Stoyan <vvvv@ydb.tech>2024-08-29 20:11:11 +0300
committerGitHub <noreply@github.com>2024-08-29 20:11:11 +0300
commit2a8d5288ff2f30d7e81da655ef2bb2df768df750 (patch)
treedfccec3292347ef3e0f6ec423b229a815b2bb1e3
parent93089eecc92947f748b20c17c2fa0b3fa7d2b18a (diff)
downloadydb-2a8d5288ff2f30d7e81da655ef2bb2df768df750.tar.gz
result_format: type parser & builder (#8469)
-rw-r--r--ydb/library/yql/public/result_format/ut/ya.make12
-rw-r--r--ydb/library/yql/public/result_format/ut/yql_result_format_ut.cpp290
-rw-r--r--ydb/library/yql/public/result_format/ya.make16
-rw-r--r--ydb/library/yql/public/result_format/yql_result_format.cpp719
-rw-r--r--ydb/library/yql/public/result_format/yql_result_format.h207
-rw-r--r--ydb/library/yql/public/ya.make1
6 files changed, 1245 insertions, 0 deletions
diff --git a/ydb/library/yql/public/result_format/ut/ya.make b/ydb/library/yql/public/result_format/ut/ya.make
new file mode 100644
index 0000000000..ff68dbf45d
--- /dev/null
+++ b/ydb/library/yql/public/result_format/ut/ya.make
@@ -0,0 +1,12 @@
+UNITTEST_FOR(ydb/library/yql/public/result_format)
+
+SRCS(
+ yql_result_format_ut.cpp
+)
+
+PEERDIR(
+ library/cpp/yson/node
+)
+
+END()
+
diff --git a/ydb/library/yql/public/result_format/ut/yql_result_format_ut.cpp b/ydb/library/yql/public/result_format/ut/yql_result_format_ut.cpp
new file mode 100644
index 0000000000..f9fcd756b9
--- /dev/null
+++ b/ydb/library/yql/public/result_format/ut/yql_result_format_ut.cpp
@@ -0,0 +1,290 @@
+#include <ydb/library/yql/public/result_format/yql_result_format.h>
+
+#include <library/cpp/yson/node/node_io.h>
+
+#include <library/cpp/testing/unittest/registar.h>
+
+namespace NYql::NResult {
+
+void Test(const TString& input) {
+ TTypeBuilder builder;
+ auto node = NYT::NodeFromYsonString(input);
+ ParseType(node, builder);
+ UNIT_ASSERT_VALUES_EQUAL(NYT::NodeToCanonicalYsonString(builder.GetResult()), NYT::NodeToCanonicalYsonString(node));
+}
+
+Y_UNIT_TEST_SUITE(TParseType) {
+ Y_UNIT_TEST(Throwing) {
+ TThrowingTypeVisitor v;
+ UNIT_ASSERT_EXCEPTION(v.OnNull(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnVoid(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnEmptyList(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnEmptyDict(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnBool(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnInt8(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnUint8(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnInt16(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnUint16(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnInt32(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnUint32(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnInt64(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnUint64(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnFloat(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnDouble(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnString(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnUtf8(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnYson(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnJson(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnJsonDocument(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnUuid(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnDyNumber(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnDate(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnDatetime(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnTimestamp(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnTzDate(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnTzDatetime(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnTzTimestamp(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnInterval(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnDate32(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnDatetime64(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnTimestamp64(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnTzDate32(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnTzDatetime64(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnTzTimestamp64(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnInterval64(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnDecimal(10, 1), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnBeginOptional(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnEndOptional(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnBeginList(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnEndList(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnBeginTuple(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnTupleItem(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnEndTuple(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnBeginStruct(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnStructItem("foo"), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnEndStruct(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnBeginDict(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnDictKey(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnDictPayload(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnEndDict(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnBeginVariant(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnEndVariant(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnBeginTagged("foo"), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnEndTagged(), TUnsupportedException);
+ UNIT_ASSERT_EXCEPTION(v.OnPgType("int4", "N"), TUnsupportedException);
+ }
+
+ Y_UNIT_TEST(BadNotList) {
+ UNIT_ASSERT_EXCEPTION(Test("foo"), TUnsupportedException);
+ }
+
+ Y_UNIT_TEST(BadEmptyList) {
+ UNIT_ASSERT_EXCEPTION(Test("[]"), TUnsupportedException);
+ }
+
+ Y_UNIT_TEST(BadNotStringName) {
+ UNIT_ASSERT_EXCEPTION(Test("[#]"), TUnsupportedException);
+ }
+
+ Y_UNIT_TEST(BadUnknownName) {
+ UNIT_ASSERT_EXCEPTION(Test("[unknown]"), TUnsupportedException);
+ }
+
+ Y_UNIT_TEST(Void) {
+ Test("[VoidType]");
+ }
+
+ Y_UNIT_TEST(Null) {
+ Test("[NullType]");
+ }
+
+ Y_UNIT_TEST(EmptyList) {
+ Test("[EmptyListType]");
+ }
+
+ Y_UNIT_TEST(EmptyDict) {
+ Test("[EmptyDictType]");
+ }
+
+ Y_UNIT_TEST(BadUnknownDataName) {
+ UNIT_ASSERT_EXCEPTION(Test("[DataType;unknown]"), TUnsupportedException);
+ }
+
+ Y_UNIT_TEST(Bool) {
+ Test("[DataType;Bool]");
+ }
+
+ Y_UNIT_TEST(Int8) {
+ Test("[DataType;Int8]");
+ }
+
+ Y_UNIT_TEST(Uint8) {
+ Test("[DataType;Uint8]");
+ }
+
+ Y_UNIT_TEST(Int16) {
+ Test("[DataType;Int16]");
+ }
+
+ Y_UNIT_TEST(Uint16) {
+ Test("[DataType;Uint16]");
+ }
+
+ Y_UNIT_TEST(Int32) {
+ Test("[DataType;Int32]");
+ }
+
+ Y_UNIT_TEST(Uint32) {
+ Test("[DataType;Uint32]");
+ }
+
+ Y_UNIT_TEST(Int64) {
+ Test("[DataType;Int64]");
+ }
+
+ Y_UNIT_TEST(Uint64) {
+ Test("[DataType;Uint64]");
+ }
+
+ Y_UNIT_TEST(Float) {
+ Test("[DataType;Float]");
+ }
+
+ Y_UNIT_TEST(Double) {
+ Test("[DataType;Double]");
+ }
+
+ Y_UNIT_TEST(String) {
+ Test("[DataType;String]");
+ }
+
+ Y_UNIT_TEST(Utf8) {
+ Test("[DataType;Utf8]");
+ }
+
+ Y_UNIT_TEST(Yson) {
+ Test("[DataType;Yson]");
+ }
+
+ Y_UNIT_TEST(Json) {
+ Test("[DataType;Json]");
+ }
+
+ Y_UNIT_TEST(JsonDocument) {
+ Test("[DataType;JsonDocument]");
+ }
+
+ Y_UNIT_TEST(Uuid) {
+ Test("[DataType;Uuid]");
+ }
+
+ Y_UNIT_TEST(DyNumber) {
+ Test("[DataType;DyNumber]");
+ }
+
+ Y_UNIT_TEST(Date) {
+ Test("[DataType;Date]");
+ }
+
+ Y_UNIT_TEST(Datetime) {
+ Test("[DataType;Datetime]");
+ }
+
+ Y_UNIT_TEST(Timestamp) {
+ Test("[DataType;Timestamp]");
+ }
+
+ Y_UNIT_TEST(TzDate) {
+ Test("[DataType;TzDate]");
+ }
+
+ Y_UNIT_TEST(TzDatetime) {
+ Test("[DataType;TzDatetime]");
+ }
+
+ Y_UNIT_TEST(TzTimestamp) {
+ Test("[DataType;TzTimestamp]");
+ }
+
+ Y_UNIT_TEST(Interval) {
+ Test("[DataType;Interval]");
+ }
+
+ Y_UNIT_TEST(Date32) {
+ Test("[DataType;Date32]");
+ }
+
+ Y_UNIT_TEST(Datetime64) {
+ Test("[DataType;Datetime64]");
+ }
+
+ Y_UNIT_TEST(Timestamp64) {
+ Test("[DataType;Timestamp64]");
+ }
+
+ Y_UNIT_TEST(TzDate32) {
+ Test("[DataType;TzDate32]");
+ }
+
+ Y_UNIT_TEST(TzDatetime64) {
+ Test("[DataType;TzDatetime64]");
+ }
+
+ Y_UNIT_TEST(TzTimestamp64) {
+ Test("[DataType;TzTimestamp64]");
+ }
+
+ Y_UNIT_TEST(Interval64) {
+ Test("[DataType;Interval64]");
+ }
+
+ Y_UNIT_TEST(Decimal) {
+ Test("[DataType;Decimal;\"10\";\"1\"]");
+ }
+
+ Y_UNIT_TEST(OptionalInt32) {
+ Test("[OptionalType;[DataType;Int32]]");
+ }
+
+ Y_UNIT_TEST(ListInt32) {
+ Test("[ListType;[DataType;Int32]]");
+ }
+
+ Y_UNIT_TEST(ListListInt32) {
+ Test("[ListType;[ListType;[DataType;Int32]]]");
+ }
+
+ Y_UNIT_TEST(TupleInt32String) {
+ Test("[TupleType;[[DataType;Int32];[DataType;String]]]");
+ }
+
+ Y_UNIT_TEST(EmptyTuple) {
+ Test("[TupleType;[]]");
+ }
+
+ Y_UNIT_TEST(StructInt32String) {
+ Test("[StructType;[[foo;[DataType;Int32]];[bar;[DataType;String]]]]");
+ }
+
+ Y_UNIT_TEST(EmptyStruct) {
+ Test("[StructType;[]]");
+ }
+
+ Y_UNIT_TEST(DictInt32String) {
+ Test("[DictType;[DataType;Int32];[DataType;String]]");
+ }
+
+ Y_UNIT_TEST(VariantTupleInt32String) {
+ Test("[VariantType;[TupleType;[[DataType;Int32];[DataType;String]]]]");
+ }
+
+ Y_UNIT_TEST(TaggedInt32) {
+ Test("[TaggedType;foo;[DataType;Int32]]");
+ }
+
+ Y_UNIT_TEST(PgType) {
+ Test("[PgType;int4;N]");
+ }
+}
+
+}
diff --git a/ydb/library/yql/public/result_format/ya.make b/ydb/library/yql/public/result_format/ya.make
new file mode 100644
index 0000000000..11e30cf4af
--- /dev/null
+++ b/ydb/library/yql/public/result_format/ya.make
@@ -0,0 +1,16 @@
+LIBRARY()
+
+SRCS(
+ yql_result_format.cpp
+)
+
+PEERDIR(
+ library/cpp/yson/node
+)
+
+END()
+
+RECURSE_FOR_TESTS(
+ ut
+)
+
diff --git a/ydb/library/yql/public/result_format/yql_result_format.cpp b/ydb/library/yql/public/result_format/yql_result_format.cpp
new file mode 100644
index 0000000000..0bb85ccfb2
--- /dev/null
+++ b/ydb/library/yql/public/result_format/yql_result_format.cpp
@@ -0,0 +1,719 @@
+#include "yql_result_format.h"
+
+namespace NYql::NResult {
+
+namespace {
+ void Check(bool value, const TSourceLocation& location) {
+ if (!value) {
+ throw location + TUnsupportedException();
+ }
+ }
+
+ NYT::TNode MakeDataType(const TString& name) {
+ return NYT::TNode().Add("DataType").Add(name);
+ }
+}
+
+#define CHECK(value) Check(value, __LOCATION__)
+#define UNEXPECTED ythrow TUnsupportedException() << "Unhandled case"
+
+void ParseType(const NYT::TNode& typeNode, ITypeVisitor& visitor) {
+ CHECK(typeNode.IsList());
+ CHECK(typeNode.AsList().size() >= 1);
+ CHECK(typeNode.AsList()[0].IsString());
+ const auto& name = typeNode.AsList()[0].AsString();
+ if (name == "VoidType") {
+ CHECK(typeNode.AsList().size() == 1);
+ visitor.OnVoid();
+ } else if (name == "NullType") {
+ CHECK(typeNode.AsList().size() == 1);
+ visitor.OnNull();
+ } else if (name == "EmptyListType") {
+ CHECK(typeNode.AsList().size() == 1);
+ visitor.OnEmptyList();
+ } else if (name == "EmptyDictType") {
+ CHECK(typeNode.AsList().size() == 1);
+ visitor.OnEmptyDict();
+ } else if (name == "DataType") {
+ CHECK(typeNode.AsList().size() >= 2);
+ CHECK(typeNode.AsList()[1].IsString());
+ const auto& dataName = typeNode.AsList()[1].AsString();
+ if (dataName == "Bool") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnBool();
+ } else if (dataName == "Int8") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnInt8();
+ } else if (dataName == "Uint8") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnUint8();
+ } else if (dataName == "Int16") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnInt16();
+ } else if (dataName == "Uint16") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnUint16();
+ } else if (dataName == "Int32") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnInt32();
+ } else if (dataName == "Uint32") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnUint32();
+ } else if (dataName == "Int64") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnInt64();
+ } else if (dataName == "Uint64") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnUint64();
+ } else if (dataName == "Float") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnFloat();
+ } else if (dataName == "Double") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnDouble();
+ } else if (dataName == "String") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnString();
+ } else if (dataName == "Utf8") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnUtf8();
+ } else if (dataName == "Yson") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnYson();
+ } else if (dataName == "Json") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnJson();
+ } else if (dataName == "JsonDocument") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnJsonDocument();
+ } else if (dataName == "Uuid") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnUuid();
+ } else if (dataName == "DyNumber") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnDyNumber();
+ } else if (dataName == "Date") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnDate();
+ } else if (dataName == "Datetime") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnDatetime();
+ } else if (dataName == "Timestamp") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnTimestamp();
+ } else if (dataName == "TzDate") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnTzDate();
+ } else if (dataName == "TzDatetime") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnTzDatetime();
+ } else if (dataName == "TzTimestamp") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnTzTimestamp();
+ } else if (dataName == "Interval") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnInterval();
+ } else if (dataName == "Date32") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnDate32();
+ } else if (dataName == "Datetime64") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnDatetime64();
+ } else if (dataName == "Timestamp64") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnTimestamp64();
+ } else if (dataName == "TzDate32") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnTzDate32();
+ } else if (dataName == "TzDatetime64") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnTzDatetime64();
+ } else if (dataName == "TzTimestamp64") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnTzTimestamp64();
+ } else if (dataName == "Interval64") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnInterval64();
+ } else if (dataName == "Decimal") {
+ CHECK(typeNode.AsList().size() == 4);
+ CHECK(typeNode.AsList()[2].IsString());
+ CHECK(typeNode.AsList()[3].IsString());
+ ui32 precision;
+ ui32 scale;
+ CHECK(TryFromString(typeNode.AsList()[2].AsString(), precision));
+ CHECK(TryFromString(typeNode.AsList()[3].AsString(), scale));
+ visitor.OnDecimal(precision, scale);
+ } else {
+ ythrow TUnsupportedException() << "Unexpected data type name: " << dataName;
+ }
+ } else if (name == "OptionalType") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnBeginOptional();
+ ParseType(typeNode.AsList()[1], visitor);
+ visitor.OnEndOptional();
+ } else if (name == "ListType") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnBeginList();
+ ParseType(typeNode.AsList()[1], visitor);
+ visitor.OnEndList();
+ } else if (name == "TupleType") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnBeginTuple();
+ CHECK(typeNode.AsList()[1].IsList());
+ for (const auto& v : typeNode.AsList()[1].AsList()) {
+ visitor.OnTupleItem();
+ ParseType(v, visitor);
+ }
+
+ visitor.OnEndTuple();
+ } else if (name == "StructType") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnBeginStruct();
+ CHECK(typeNode.AsList()[1].IsList());
+ for (const auto& v : typeNode.AsList()[1].AsList()) {
+ CHECK(v.IsList());
+ CHECK(v.AsList().size() == 2);
+ CHECK(v.AsList()[0].IsString());
+ const auto& member = v.AsList()[0].AsString();
+ visitor.OnStructItem(member);
+ ParseType(v.AsList()[1], visitor);
+ }
+
+ visitor.OnEndStruct();
+ } else if (name == "DictType") {
+ CHECK(typeNode.AsList().size() == 3);
+ visitor.OnBeginDict();
+ visitor.OnDictKey();
+ ParseType(typeNode.AsList()[1], visitor);
+ visitor.OnDictPayload();
+ ParseType(typeNode.AsList()[2], visitor);
+ visitor.OnEndDict();
+ } else if (name == "VariantType") {
+ CHECK(typeNode.AsList().size() == 2);
+ visitor.OnBeginVariant();
+ ParseType(typeNode.AsList()[1], visitor);
+ visitor.OnEndVariant();
+ } else if (name == "TaggedType") {
+ CHECK(typeNode.AsList().size() == 3);
+ CHECK(typeNode.AsList()[1].IsString());
+ visitor.OnBeginTagged(typeNode.AsList()[1].AsString());
+ ParseType(typeNode.AsList()[2], visitor);
+ visitor.OnEndTagged();
+ } else if (name == "PgType") {
+ CHECK(typeNode.AsList().size() == 3);
+ CHECK(typeNode.AsList()[1].IsString());
+ CHECK(typeNode.AsList()[2].IsString());
+ visitor.OnPgType(typeNode.AsList()[1].AsString(), typeNode.AsList()[2].AsString());
+ } else {
+ ythrow TUnsupportedException() << "Unexpected type name: " << name;
+ }
+}
+
+TTypeBuilder::TTypeBuilder() {
+ Stack.push_back(&Root);
+}
+
+const NYT::TNode& TTypeBuilder::GetResult() const {
+ CHECK(Stack.size() == 1);
+ return Root;
+}
+
+void TTypeBuilder::OnVoid() {
+ Top() = NYT::TNode().Add("VoidType");
+}
+
+void TTypeBuilder::OnNull() {
+ Top() = NYT::TNode().Add("NullType");
+}
+
+void TTypeBuilder::OnEmptyList() {
+ Top() = NYT::TNode().Add("EmptyListType");
+}
+
+void TTypeBuilder::OnEmptyDict() {
+ Top() = NYT::TNode().Add("EmptyDictType");
+}
+
+void TTypeBuilder::OnBool() {
+ Top() = MakeDataType("Bool");
+}
+
+void TTypeBuilder::OnInt8() {
+ Top() = MakeDataType("Int8");
+}
+
+void TTypeBuilder::OnUint8() {
+ Top() = MakeDataType("Uint8");
+}
+
+void TTypeBuilder::OnInt16() {
+ Top() = MakeDataType("Int16");
+}
+
+void TTypeBuilder::OnUint16() {
+ Top() = MakeDataType("Uint16");
+}
+
+void TTypeBuilder::OnInt32() {
+ Top() = MakeDataType("Int32");
+}
+
+void TTypeBuilder::OnUint32() {
+ Top() = MakeDataType("Uint32");
+}
+
+void TTypeBuilder::OnInt64() {
+ Top() = MakeDataType("Int64");
+}
+
+void TTypeBuilder::OnUint64() {
+ Top() = MakeDataType("Uint64");
+}
+
+void TTypeBuilder::OnFloat() {
+ Top() = MakeDataType("Float");
+}
+
+void TTypeBuilder::OnDouble() {
+ Top() = MakeDataType("Double");
+}
+
+void TTypeBuilder::OnString() {
+ Top() = MakeDataType("String");
+}
+
+void TTypeBuilder::OnUtf8() {
+ Top() = MakeDataType("Utf8");
+}
+
+void TTypeBuilder::OnYson() {
+ Top() = MakeDataType("Yson");
+}
+
+void TTypeBuilder::OnJson() {
+ Top() = MakeDataType("Json");
+}
+
+void TTypeBuilder::OnJsonDocument() {
+ Top() = MakeDataType("JsonDocument");
+}
+
+void TTypeBuilder::OnUuid() {
+ Top() = MakeDataType("Uuid");
+}
+
+void TTypeBuilder::OnDyNumber() {
+ Top() = MakeDataType("DyNumber");
+}
+
+void TTypeBuilder::OnDate() {
+ Top() = MakeDataType("Date");
+}
+
+void TTypeBuilder::OnDatetime() {
+ Top() = MakeDataType("Datetime");
+}
+
+void TTypeBuilder::OnTimestamp() {
+ Top() = MakeDataType("Timestamp");
+}
+
+void TTypeBuilder::OnTzDate() {
+ Top() = MakeDataType("TzDate");
+}
+
+void TTypeBuilder::OnTzDatetime() {
+ Top() = MakeDataType("TzDatetime");
+}
+
+void TTypeBuilder::OnTzTimestamp() {
+ Top() = MakeDataType("TzTimestamp");
+}
+
+void TTypeBuilder::OnInterval() {
+ Top() = MakeDataType("Interval");
+}
+
+void TTypeBuilder::OnDate32() {
+ Top() = MakeDataType("Date32");
+}
+
+void TTypeBuilder::OnDatetime64() {
+ Top() = MakeDataType("Datetime64");
+}
+
+void TTypeBuilder::OnTimestamp64() {
+ Top() = MakeDataType("Timestamp64");
+}
+
+void TTypeBuilder::OnTzDate32() {
+ Top() = MakeDataType("TzDate32");
+}
+
+void TTypeBuilder::OnTzDatetime64() {
+ Top() = MakeDataType("TzDatetime64");
+}
+
+void TTypeBuilder::OnTzTimestamp64() {
+ Top() = MakeDataType("TzTimestamp64");
+}
+
+void TTypeBuilder::OnInterval64() {
+ Top() = MakeDataType("Interval64");
+}
+
+void TTypeBuilder::OnDecimal(ui32 precision, ui32 scale) {
+ Top() = NYT::TNode().Add("DataType").Add("Decimal")
+ .Add(ToString(precision)).Add(ToString(scale));
+}
+
+NYT::TNode& TTypeBuilder::Top() {
+ return *Stack.back();
+}
+
+void TTypeBuilder::OnBeginOptional() {
+ Top() = NYT::TNode().Add("OptionalType");
+ Push();
+}
+
+void TTypeBuilder::OnEndOptional() {
+ Pop();
+}
+
+void TTypeBuilder::OnBeginList() {
+ Top() = NYT::TNode().Add("ListType");
+ Push();
+}
+
+void TTypeBuilder::OnEndList() {
+ Pop();
+}
+
+void TTypeBuilder::OnBeginTuple() {
+ Top() = NYT::TNode().Add("TupleType").Add(NYT::TNode::CreateList());
+ Stack.push_back(&Top().AsList()[1]);
+}
+
+void TTypeBuilder::OnTupleItem() {
+ if (!Top().AsList().empty()) {
+ Pop();
+ }
+
+ Push();
+}
+
+void TTypeBuilder::OnEndTuple() {
+ if (!Top().AsList().empty()) {
+ Pop();
+ }
+
+ Pop();
+}
+
+void TTypeBuilder::OnBeginStruct() {
+ Top() = NYT::TNode().Add("StructType").Add(NYT::TNode::CreateList());
+ Stack.push_back(&Top().AsList()[1]);
+}
+
+void TTypeBuilder::OnStructItem(TStringBuf member) {
+ if (!Top().AsList().empty()) {
+ Pop();
+ }
+
+ Top().Add(NYT::TNode::CreateList());
+ auto& pair = Top().AsList().back();
+ pair.Add(member);
+ auto ptr = &pair.Add();
+ Stack.push_back(ptr);
+}
+
+void TTypeBuilder::OnEndStruct() {
+ if (!Top().AsList().empty()) {
+ Pop();
+ }
+
+ Pop();
+}
+
+void TTypeBuilder::OnBeginDict() {
+ Top() = NYT::TNode().Add("DictType");
+ Stack.push_back(&Top());
+}
+
+
+void TTypeBuilder::OnDictKey() {
+ Push();
+}
+
+void TTypeBuilder::OnDictPayload() {
+ Pop();
+ Push();
+}
+
+void TTypeBuilder::OnEndDict() {
+ Pop();
+ Pop();
+}
+
+void TTypeBuilder::OnBeginVariant() {
+ Top() = NYT::TNode().Add("VariantType");
+ Push();
+}
+
+void TTypeBuilder::OnEndVariant() {
+ Pop();
+}
+
+void TTypeBuilder::OnBeginTagged(TStringBuf tag) {
+ Top() = NYT::TNode().Add("TaggedType").Add(tag);
+ Push();
+}
+
+void TTypeBuilder::OnEndTagged() {
+ Pop();
+}
+
+void TTypeBuilder::OnPgType(TStringBuf name, TStringBuf category) {
+ Top() = NYT::TNode().Add("PgType").Add(name).Add(category);
+}
+
+void TTypeBuilder::Push() {
+ auto ptr = &Top().Add();
+ Stack.push_back(ptr);
+}
+
+void TTypeBuilder::Pop() {
+ Stack.pop_back();
+}
+
+void TThrowingTypeVisitor::OnVoid() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnNull() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnEmptyList() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnEmptyDict() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnBool() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnInt8() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnUint8() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnInt16() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnUint16() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnInt32() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnUint32() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnInt64() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnUint64() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnFloat() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnDouble() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnString() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnUtf8() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnYson() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnJson() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnJsonDocument() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnUuid() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnDyNumber() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnDate() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnDatetime() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnTimestamp() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnTzDate() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnTzDatetime() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnTzTimestamp() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnInterval() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnDate32() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnDatetime64() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnTimestamp64() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnTzDate32() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnTzDatetime64() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnTzTimestamp64() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnInterval64() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnDecimal(ui32 precision, ui32 scale) {
+ Y_UNUSED(precision);
+ Y_UNUSED(scale);
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnBeginOptional() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnEndOptional() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnBeginList() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnEndList() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnBeginTuple() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnTupleItem() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnEndTuple() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnBeginStruct() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnStructItem(TStringBuf member) {
+ Y_UNUSED(member);
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnEndStruct() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnBeginDict() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnDictKey() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnDictPayload() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnEndDict() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnBeginVariant() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnEndVariant() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnBeginTagged(TStringBuf tag) {
+ Y_UNUSED(tag);
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnEndTagged() {
+ UNEXPECTED;
+}
+
+void TThrowingTypeVisitor::OnPgType(TStringBuf name, TStringBuf category) {
+ Y_UNUSED(name);
+ Y_UNUSED(category);
+ UNEXPECTED;
+}
+
+}
diff --git a/ydb/library/yql/public/result_format/yql_result_format.h b/ydb/library/yql/public/result_format/yql_result_format.h
new file mode 100644
index 0000000000..cd822e9fd6
--- /dev/null
+++ b/ydb/library/yql/public/result_format/yql_result_format.h
@@ -0,0 +1,207 @@
+#pragma once
+
+#include <library/cpp/yson/node/node.h>
+#include <library/cpp/yson/node/node.h>
+
+namespace NYql::NResult {
+
+class TUnsupportedException : public yexception {};
+
+class ITypeVisitor {
+public:
+ virtual ~ITypeVisitor() = default;
+
+ virtual void OnVoid() = 0;
+ virtual void OnNull() = 0;
+ virtual void OnEmptyList() = 0;
+ virtual void OnEmptyDict() = 0;
+ virtual void OnBool() = 0;
+ virtual void OnInt8() = 0;
+ virtual void OnUint8() = 0;
+ virtual void OnInt16() = 0;
+ virtual void OnUint16() = 0;
+ virtual void OnInt32() = 0;
+ virtual void OnUint32() = 0;
+ virtual void OnInt64() = 0;
+ virtual void OnUint64() = 0;
+ virtual void OnFloat() = 0;
+ virtual void OnDouble() = 0;
+ virtual void OnString() = 0;
+ virtual void OnUtf8() = 0;
+ virtual void OnYson() = 0;
+ virtual void OnJson() = 0;
+ virtual void OnJsonDocument() = 0;
+ virtual void OnUuid() = 0;
+ virtual void OnDyNumber() = 0;
+ virtual void OnDate() = 0;
+ virtual void OnDatetime() = 0;
+ virtual void OnTimestamp() = 0;
+ virtual void OnTzDate() = 0;
+ virtual void OnTzDatetime() = 0;
+ virtual void OnTzTimestamp() = 0;
+ virtual void OnInterval() = 0;
+ virtual void OnDate32() = 0;
+ virtual void OnDatetime64() = 0;
+ virtual void OnTimestamp64() = 0;
+ virtual void OnTzDate32() = 0;
+ virtual void OnTzDatetime64() = 0;
+ virtual void OnTzTimestamp64() = 0;
+ virtual void OnInterval64() = 0;
+ virtual void OnDecimal(ui32 precision, ui32 scale) = 0;
+ virtual void OnBeginOptional() = 0;
+ virtual void OnEndOptional() = 0;
+ virtual void OnBeginList() = 0;
+ virtual void OnEndList() = 0;
+ virtual void OnBeginTuple() = 0;
+ virtual void OnTupleItem() = 0;
+ virtual void OnEndTuple() = 0;
+ virtual void OnBeginStruct() = 0;
+ virtual void OnStructItem(TStringBuf member) = 0;
+ virtual void OnEndStruct() = 0;
+ virtual void OnBeginDict() = 0;
+ virtual void OnDictKey() = 0;
+ virtual void OnDictPayload() = 0;
+ virtual void OnEndDict() = 0;
+ virtual void OnBeginVariant() = 0;
+ virtual void OnEndVariant() = 0;
+ virtual void OnBeginTagged(TStringBuf tag) = 0;
+ virtual void OnEndTagged() = 0;
+ virtual void OnPgType(TStringBuf name, TStringBuf category) = 0;
+};
+
+class TThrowingTypeVisitor : public ITypeVisitor {
+public:
+ void OnVoid() override;
+ void OnNull() override;
+ void OnEmptyList() override;
+ void OnEmptyDict() override;
+ void OnBool() override;
+ void OnInt8() override;
+ void OnUint8() override;
+ void OnInt16() override;
+ void OnUint16() override;
+ void OnInt32() override;
+ void OnUint32() override;
+ void OnInt64() override;
+ void OnUint64() override;
+ void OnFloat() override;
+ void OnDouble() override;
+ void OnString() override;
+ void OnUtf8() override;
+ void OnYson() override;
+ void OnJson() override;
+ void OnJsonDocument() override;
+ void OnUuid() override;
+ void OnDyNumber() override;
+ void OnDate() override;
+ void OnDatetime() override;
+ void OnTimestamp() override;
+ void OnTzDate() override;
+ void OnTzDatetime() override;
+ void OnTzTimestamp() override;
+ void OnInterval() override;
+ void OnDate32() override;
+ void OnDatetime64() override;
+ void OnTimestamp64() override;
+ void OnTzDate32() override;
+ void OnTzDatetime64() override;
+ void OnTzTimestamp64() override;
+ void OnInterval64() override;
+ void OnDecimal(ui32 precision, ui32 scale) override;
+ void OnBeginOptional() override;
+ void OnEndOptional() override;
+ void OnBeginList() override;
+ void OnEndList() override;
+ void OnBeginTuple() override;
+ void OnTupleItem() override;
+ void OnEndTuple() override;
+ void OnBeginStruct() override;
+ void OnStructItem(TStringBuf member) override;
+ void OnEndStruct() override;
+ void OnBeginDict() override;
+ void OnDictKey() override;
+ void OnDictPayload() override;
+ void OnEndDict() override;
+ void OnBeginVariant() override;
+ void OnEndVariant() override;
+ void OnBeginTagged(TStringBuf tag) override;
+ void OnEndTagged() override;
+ void OnPgType(TStringBuf name, TStringBuf category) override;
+};
+
+void ParseType(const NYT::TNode& typeNode, ITypeVisitor& visitor);
+
+class TTypeBuilder : public ITypeVisitor {
+public:
+ TTypeBuilder();
+ const NYT::TNode& GetResult() const;
+
+private:
+ void OnVoid() final;
+ void OnNull() final;
+ void OnEmptyList() final;
+ void OnEmptyDict() final;
+ void OnBool() final;
+ void OnInt8() final;
+ void OnUint8() final;
+ void OnInt16() final;
+ void OnUint16() final;
+ void OnInt32() final;
+ void OnUint32() final;
+ void OnInt64() final;
+ void OnUint64() final;
+ void OnFloat() final;
+ void OnDouble() final;
+ void OnString() final;
+ void OnUtf8() final;
+ void OnYson() final;
+ void OnJson() final;
+ void OnJsonDocument() final;
+ void OnUuid() final;
+ void OnDyNumber() final;
+ void OnDate() final;
+ void OnDatetime() final;
+ void OnTimestamp() final;
+ void OnTzDate() final;
+ void OnTzDatetime() final;
+ void OnTzTimestamp() final;
+ void OnInterval() final;
+ void OnDate32() final;
+ void OnDatetime64() final;
+ void OnTimestamp64() final;
+ void OnTzDate32() final;
+ void OnTzDatetime64() final;
+ void OnTzTimestamp64() final;
+ void OnInterval64() final;
+ void OnDecimal(ui32 precision, ui32 scale) final;
+ void OnBeginOptional() final;
+ void OnEndOptional() final;
+ void OnBeginList() final;
+ void OnEndList() final;
+ void OnBeginTuple() final;
+ void OnTupleItem() final;
+ void OnEndTuple() final;
+ void OnBeginStruct() final;
+ void OnStructItem(TStringBuf member) final;
+ void OnEndStruct() final;
+ void OnBeginDict() final;
+ void OnDictKey() final;
+ void OnDictPayload() final;
+ void OnEndDict() final;
+ void OnBeginVariant() final;
+ void OnEndVariant() final;
+ void OnBeginTagged(TStringBuf tag) final;
+ void OnEndTagged() final;
+ void OnPgType(TStringBuf name, TStringBuf category) final;
+
+private:
+ NYT::TNode& Top();
+ void Push();
+ void Pop();
+
+private:
+ NYT::TNode Root;
+ TVector<NYT::TNode*> Stack;
+};
+
+}
diff --git a/ydb/library/yql/public/ya.make b/ydb/library/yql/public/ya.make
index e35da51300..aeee1f06a8 100644
--- a/ydb/library/yql/public/ya.make
+++ b/ydb/library/yql/public/ya.make
@@ -4,5 +4,6 @@ RECURSE(
fastcheck
issue
purecalc
+ result_format
udf
)