diff options
author | Vitaly Stoyan <vvvv@ydb.tech> | 2024-08-29 20:11:11 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-29 20:11:11 +0300 |
commit | 2a8d5288ff2f30d7e81da655ef2bb2df768df750 (patch) | |
tree | dfccec3292347ef3e0f6ec423b229a815b2bb1e3 | |
parent | 93089eecc92947f748b20c17c2fa0b3fa7d2b18a (diff) | |
download | ydb-2a8d5288ff2f30d7e81da655ef2bb2df768df750.tar.gz |
result_format: type parser & builder (#8469)
-rw-r--r-- | ydb/library/yql/public/result_format/ut/ya.make | 12 | ||||
-rw-r--r-- | ydb/library/yql/public/result_format/ut/yql_result_format_ut.cpp | 290 | ||||
-rw-r--r-- | ydb/library/yql/public/result_format/ya.make | 16 | ||||
-rw-r--r-- | ydb/library/yql/public/result_format/yql_result_format.cpp | 719 | ||||
-rw-r--r-- | ydb/library/yql/public/result_format/yql_result_format.h | 207 | ||||
-rw-r--r-- | ydb/library/yql/public/ya.make | 1 |
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 ) |