diff --git a/ydb/core/kqp/provider/yql_kikimr_results.cpp b/ydb/core/kqp/provider/yql_kikimr_results.cpp index c80a40412556..3aa20d8d77c2 100644 --- a/ydb/core/kqp/provider/yql_kikimr_results.cpp +++ b/ydb/core/kqp/provider/yql_kikimr_results.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include namespace NYql { @@ -26,7 +26,7 @@ bool ResultsOverflow(ui64 rows, ui64 bytes, const IDataProvider::TFillSettings& return false; } -void WriteValueToYson(const TStringStream& stream, NCommon::TYsonResultWriter& writer, const NKikimrMiniKQL::TType& type, +void WriteValueToYson(const TStringStream& stream, NResult::TYsonResultWriter& writer, const NKikimrMiniKQL::TType& type, const NKikimrMiniKQL::TValue& value, const TVector* fieldsOrder, const IDataProvider::TFillSettings& fillSettings, bool& truncated, bool firstLevel = false) { @@ -333,7 +333,7 @@ void KikimrResultToYson(const TStringStream& stream, NYson::TYsonWriter& writer, const TVector& columnHints, const IDataProvider::TFillSettings& fillSettings, bool& truncated) { truncated = false; - NCommon::TYsonResultWriter resultWriter(writer); + NResult::TYsonResultWriter resultWriter(writer); WriteValueToYson(stream, resultWriter, result.GetType(), result.GetValue(), columnHints.empty() ? nullptr : &columnHints, fillSettings, truncated, true); } diff --git a/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp b/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp index 0a4729b13b42..a4b6c179846f 100644 --- a/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp +++ b/ydb/library/yql/parser/pg_wrapper/comp_factory.cpp @@ -84,7 +84,7 @@ constexpr auto PG_ERROR = ERROR; #include #include #include -#include +#include #include #include #include @@ -3699,7 +3699,7 @@ void WriteYsonValueInTableFormatPg(TOutputBuf& buf, TPgType* type, const NUdf::T } } -void WriteYsonValuePg(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, TPgType* type, +void WriteYsonValuePg(NResult::TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, TPgType* type, const TVector* structPositions) { if (!value) { writer.OnNull(); diff --git a/ydb/library/yql/parser/pg_wrapper/interface/codec.h b/ydb/library/yql/parser/pg_wrapper/interface/codec.h index f4541ba70b9a..9a3b059a14cb 100644 --- a/ydb/library/yql/parser/pg_wrapper/interface/codec.h +++ b/ydb/library/yql/parser/pg_wrapper/interface/codec.h @@ -14,11 +14,14 @@ class TPgType; } // NKikimr namespace NYql { +namespace NResult { +class TYsonResultWriter; +} + namespace NCommon { class TInputBuf; class TOutputBuf; -class TYsonResultWriter; TString PgValueToString(const NUdf::TUnboxedValuePod& value, ui32 pgTypeId); NUdf::TUnboxedValue PgValueFromString(const TStringBuf text, ui32 pgTypeId); @@ -31,7 +34,7 @@ NUdf::TUnboxedValue PgValueFromNativeBinary(const TStringBuf binary, ui32 pgType TString PgValueCoerce(const NUdf::TUnboxedValuePod& value, ui32 pgTypeId, i32 typMod, TMaybe* error); -void WriteYsonValuePg(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TPgType* type, +void WriteYsonValuePg(NResult::TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TPgType* type, const TVector* structPositions); void WriteYsonValueInTableFormatPg(TOutputBuf& buf, NKikimr::NMiniKQL::TPgType* type, const NKikimr::NUdf::TUnboxedValuePod& value, bool topLevel); diff --git a/ydb/library/yql/parser/pg_wrapper/ya.make b/ydb/library/yql/parser/pg_wrapper/ya.make index 2eb2307b0622..7c72976f8bf7 100644 --- a/ydb/library/yql/parser/pg_wrapper/ya.make +++ b/ydb/library/yql/parser/pg_wrapper/ya.make @@ -88,6 +88,7 @@ PEERDIR( ydb/library/yql/public/udf ydb/library/yql/utils ydb/library/yql/public/decimal + ydb/library/yql/public/result_format ydb/library/binary_json ydb/library/dynumber ydb/library/uuid diff --git a/ydb/library/yql/providers/common/codec/ut/ya.make b/ydb/library/yql/providers/common/codec/ut/ya.make index cf8c219546a5..ff3989041885 100644 --- a/ydb/library/yql/providers/common/codec/ut/ya.make +++ b/ydb/library/yql/providers/common/codec/ut/ya.make @@ -8,7 +8,6 @@ ENDIF() SRCS( yql_json_codec_ut.cpp - yql_restricted_yson_ut.cpp ) PEERDIR( diff --git a/ydb/library/yql/providers/common/codec/ya.make b/ydb/library/yql/providers/common/codec/ya.make index 7f6e4836e43a..1be5b346b31a 100644 --- a/ydb/library/yql/providers/common/codec/ya.make +++ b/ydb/library/yql/providers/common/codec/ya.make @@ -5,10 +5,6 @@ SRCS( yql_codec.h yql_codec_buf.cpp yql_codec_buf.h - yql_codec_results.cpp - yql_codec_results.h - yql_restricted_yson.cpp - yql_restricted_yson.h yql_codec_type_flags.cpp yql_codec_type_flags.h yql_json_codec.cpp @@ -18,6 +14,7 @@ PEERDIR( ydb/library/yql/minikql/computation ydb/library/yql/parser/pg_wrapper/interface ydb/library/yql/providers/common/mkql + ydb/library/yql/public/result_format library/cpp/yson/node library/cpp/yson library/cpp/json diff --git a/ydb/library/yql/providers/common/codec/yql_codec.cpp b/ydb/library/yql/providers/common/codec/yql_codec.cpp index d62ce8219c0b..9b5918036060 100644 --- a/ydb/library/yql/providers/common/codec/yql_codec.cpp +++ b/ydb/library/yql/providers/common/codec/yql_codec.cpp @@ -1,15 +1,14 @@ #include "yql_codec.h" -#include "yql_restricted_yson.h" #include "yql_codec_type_flags.h" #include - #include #include #include #include #include #include +#include #include #include @@ -33,7 +32,7 @@ using namespace NKikimr; using namespace NKikimr::NMiniKQL; using namespace NYson::NDetail; -void WriteYsonValueImpl(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, TType* type, +void WriteYsonValueImpl(NResult::TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, TType* type, const TVector* structPositions) { // Result format switch (type->GetKind()) { @@ -107,7 +106,7 @@ void WriteYsonValueImpl(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& return; } case NUdf::EDataSlot::Yson: - EncodeRestrictedYson(writer, value.AsStringRef()); + NResult::EncodeRestrictedYson(writer, value.AsStringRef()); return; case NUdf::EDataSlot::Date: writer.OnUint64Scalar(value.Get()); @@ -263,7 +262,7 @@ void WriteYsonValueImpl(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& void WriteYsonValue(NYson::TYsonConsumerBase& writer, const NUdf::TUnboxedValuePod& value, TType* type, const TVector* structPositions) { - TYsonResultWriter resultWriter(writer); + NResult::TYsonResultWriter resultWriter(writer); WriteYsonValueImpl(resultWriter, value, type, structPositions); } @@ -1030,7 +1029,7 @@ NUdf::TUnboxedValue ReadYsonValue(TType* type, ui64 nativeYtTypeFlags, return NUdf::TUnboxedValue(MakeString(NUdf::TStringRef(yson))); } - TString decodedYson = DecodeRestrictedYson(TStringBuf(yson.data(), yson.size()), NYson::EYsonFormat::Text); + TString decodedYson = NResult::DecodeRestrictedYson(TStringBuf(yson.data(), yson.size()), NYson::EYsonFormat::Text); return NUdf::TUnboxedValue(MakeString(NUdf::TStringRef(decodedYson))); } @@ -1436,7 +1435,7 @@ NUdf::TUnboxedValue ReadYsonValue(TType* type, ui64 nativeYtTypeFlags, } auto nextString = ReadNextString(cmd, buf); - YQL_ENSURE(nextString == TYsonResultWriter::VoidString, "Expected Void"); + YQL_ENSURE(nextString == NResult::TYsonResultWriter::VoidString, "Expected Void"); return NUdf::TUnboxedValuePod::Void(); } diff --git a/ydb/library/yql/providers/yt/codec/ya.make b/ydb/library/yql/providers/yt/codec/ya.make index 9298c9230de0..a1318c4d49c1 100644 --- a/ydb/library/yql/providers/yt/codec/ya.make +++ b/ydb/library/yql/providers/yt/codec/ya.make @@ -18,6 +18,7 @@ PEERDIR( ydb/library/yql/minikql ydb/library/yql/public/udf ydb/library/yql/utils + ydb/library/yql/public/result_format ydb/library/yql/providers/common/codec ydb/library/yql/providers/common/schema/mkql ydb/library/yql/providers/common/schema/parser diff --git a/ydb/library/yql/providers/yt/codec/yt_codec_io.cpp b/ydb/library/yql/providers/yt/codec/yt_codec_io.cpp index 2b14d0c48d1a..31245092ddbf 100644 --- a/ydb/library/yql/providers/yt/codec/yt_codec_io.cpp +++ b/ydb/library/yql/providers/yt/codec/yt_codec_io.cpp @@ -1,6 +1,6 @@ #include "yt_codec_io.h" -#include +#include #include #include #include @@ -2225,7 +2225,7 @@ void DecodeToYson(TMkqlIOCache& specsCache, size_t tableIndex, const NYT::TNode& } if (res.GetType() != NYT::TNode::Undefined) { if (dataType->GetKind() == TType::EKind::Data && static_cast(dataType)->GetSchemeType() == NUdf::TDataType::Id) { - items[field->StructIndex] = NCommon::EncodeRestrictedYson(res, NYT::NYson::EYsonFormat::Binary); + items[field->StructIndex] = NResult::EncodeRestrictedYson(res, NYT::NYson::EYsonFormat::Binary); } else { items[field->StructIndex] = NYT::NodeToYsonString(res, NYT::NYson::EYsonFormat::Binary); } diff --git a/ydb/library/yql/public/result_format/ut/ya.make b/ydb/library/yql/public/result_format/ut/ya.make index ff68dbf45d96..f73a5206442a 100644 --- a/ydb/library/yql/public/result_format/ut/ya.make +++ b/ydb/library/yql/public/result_format/ut/ya.make @@ -1,12 +1,15 @@ UNITTEST_FOR(ydb/library/yql/public/result_format) SRCS( - yql_result_format_ut.cpp + yql_result_format_response_ut.cpp + yql_result_format_type_ut.cpp + yql_result_format_data_ut.cpp + yql_restricted_yson_ut.cpp ) PEERDIR( library/cpp/yson/node + library/cpp/string_utils/base64 ) END() - diff --git a/ydb/library/yql/providers/common/codec/yql_restricted_yson_ut.cpp b/ydb/library/yql/public/result_format/ut/yql_restricted_yson_ut.cpp similarity index 96% rename from ydb/library/yql/providers/common/codec/yql_restricted_yson_ut.cpp rename to ydb/library/yql/public/result_format/ut/yql_restricted_yson_ut.cpp index aee6715a93a8..2175ce63f706 100644 --- a/ydb/library/yql/providers/common/codec/yql_restricted_yson_ut.cpp +++ b/ydb/library/yql/public/result_format/ut/yql_restricted_yson_ut.cpp @@ -27,9 +27,9 @@ TString Normalize(const TString& yson) { Y_UNIT_TEST_SUITE(TRestrictedYson) { void RunTest(const NYT::TNode& node, const TString& expectedNodeStr, const TString& expectedEncodedStr) { UNIT_ASSERT_VALUES_EQUAL(FormatNode(node), expectedNodeStr); - TString encoded = NCommon::EncodeRestrictedYson(node, NYson::EYsonFormat::Text); + TString encoded = NResult::EncodeRestrictedYson(node, NYson::EYsonFormat::Text); UNIT_ASSERT_VALUES_EQUAL(Normalize(encoded), expectedEncodedStr); - TString decoded = NCommon::DecodeRestrictedYson(TStringBuf(encoded), NYson::EYsonFormat::Text); + TString decoded = NResult::DecodeRestrictedYson(TStringBuf(encoded), NYson::EYsonFormat::Text); UNIT_ASSERT_VALUES_EQUAL(FormatNode(node), Normalize(decoded)); } diff --git a/ydb/library/yql/public/result_format/ut/yql_result_format_data_ut.cpp b/ydb/library/yql/public/result_format/ut/yql_result_format_data_ut.cpp new file mode 100644 index 000000000000..17788d4cc5a0 --- /dev/null +++ b/ydb/library/yql/public/result_format/ut/yql_result_format_data_ut.cpp @@ -0,0 +1,396 @@ +#include +#include + +#include + +#include + +namespace NYql::NResult { + +void Test(const TString& inputType, const TString& inputData, const TMaybe& altData = Nothing()) { + TDataBuilder builder; + auto nodeType = NYT::NodeFromYsonString(inputType); + auto nodeData = NYT::NodeFromYsonString(inputData); + ParseData(nodeType, nodeData, builder); + UNIT_ASSERT_VALUES_EQUAL(NYT::NodeToCanonicalYsonString(builder.GetResult()), NYT::NodeToCanonicalYsonString(nodeData)); + if (altData.Defined()) { + TDataBuilder builder2; + auto nodeData2 = NYT::NodeFromYsonString(*altData); + ParseData(nodeType, nodeData2, builder2); + UNIT_ASSERT_VALUES_EQUAL(NYT::NodeToCanonicalYsonString(builder2.GetResult()), NYT::NodeToCanonicalYsonString(nodeData)); + } +} + +Y_UNIT_TEST_SUITE(ParseData) { + Y_UNIT_TEST(EmptyVisitor) { + TEmptyDataVisitor v; + v.OnVoid(); + v.OnNull(); + v.OnEmptyList(); + v.OnEmptyDict(); + v.OnBool(true); + v.OnInt8(1); + v.OnUint8(1); + v.OnInt16(1); + v.OnUint16(1); + v.OnInt32(1); + v.OnUint32(1); + v.OnInt64(1); + v.OnUint64(1); + v.OnFloat(1.2f); + v.OnDouble(1.2f); + v.OnString("foo", true); + v.OnUtf8("foo"); + v.OnYson("foo", true); + v.OnJson("foo"); + v.OnJsonDocument("foo"); + v.OnUuid("foo", true); + v.OnDyNumber("foo", true); + v.OnDate(1); + v.OnDatetime(1); + v.OnTimestamp(1); + v.OnTzDate("foo"); + v.OnTzDatetime("foo"); + v.OnTzTimestamp("foo"); + v.OnInterval(1); + v.OnDate32(1); + v.OnDatetime64(1); + v.OnTimestamp64(1); + v.OnTzDate32("foo"); + v.OnTzDatetime64("foo"); + v.OnTzTimestamp64("foo"); + v.OnInterval64(1); + v.OnDecimal("1.2"); + v.OnBeginOptional(); + v.OnBeforeOptionalItem(); + v.OnAfterOptionalItem(); + v.OnEmptyOptional(); + v.OnEndOptional(); + v.OnBeginList(); + v.OnBeforeListItem(); + v.OnAfterListItem(); + v.OnEndList(); + v.OnBeginTuple(); + v.OnBeforeTupleItem(); + v.OnAfterTupleItem(); + v.OnEndTuple(); + v.OnBeginStruct(); + v.OnBeforeStructItem(); + v.OnAfterStructItem(); + v.OnEndStruct(); + v.OnBeginDict(); + v.OnBeforeDictItem(); + v.OnBeforeDictKey(); + v.OnAfterDictKey(); + v.OnBeforeDictPayload(); + v.OnAfterDictPayload(); + v.OnAfterDictItem(); + v.OnEndDict(); + v.OnBeginVariant(0); + v.OnEndVariant(); + v.OnPg("foo",true); + } + + Y_UNIT_TEST(ThrowingVisitor) { + TThrowingDataVisitor v; + UNIT_ASSERT_EXCEPTION(v.OnVoid(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnNull(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnEmptyList(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnEmptyDict(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBool(true), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnInt8(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnUint8(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnInt16(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnUint16(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnInt32(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnUint32(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnInt64(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnUint64(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnFloat(1.2f), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnDouble(1.2f), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnString("foo", true), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnUtf8("foo"), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnYson("foo", true), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnJson("foo"), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnJsonDocument("foo"), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnUuid("foo", true), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnDyNumber("foo", true), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnDate(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnDatetime(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnTimestamp(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnTzDate("foo"), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnTzDatetime("foo"), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnTzTimestamp("foo"), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnInterval(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnDate32(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnDatetime64(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnTimestamp64(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnTzDate32("foo"), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnTzDatetime64("foo"), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnTzTimestamp64("foo"), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnInterval64(1), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnDecimal("1.2"), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeginOptional(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeforeOptionalItem(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnAfterOptionalItem(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnEmptyOptional(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnEndOptional(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeginList(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeforeListItem(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnAfterListItem(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnEndList(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeginTuple(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeforeTupleItem(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnAfterTupleItem(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnEndTuple(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeginStruct(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeforeStructItem(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnAfterStructItem(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnEndStruct(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeginDict(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeforeDictItem(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeforeDictKey(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnAfterDictKey(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeforeDictPayload(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnAfterDictPayload(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnAfterDictItem(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnEndDict(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnBeginVariant(0), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnEndVariant(), TUnsupportedException); + UNIT_ASSERT_EXCEPTION(v.OnPg("foo",true), TUnsupportedException); + } + + Y_UNIT_TEST(Void) { + Test("[VoidType]","Void"); + } + + Y_UNIT_TEST(Null) { + Test("[NullType]","#"); + } + + Y_UNIT_TEST(EmptyList) { + Test("[EmptyListType]","[]"); + } + + Y_UNIT_TEST(EmptyDict) { + Test("[EmptyDictType]","[]"); + } + + Y_UNIT_TEST(Bool) { + Test("[DataType;Bool]","%true"); + Test("[DataType;Bool]","%false"); + } + + Y_UNIT_TEST(Int8) { + Test("[DataType;Int8]","\"1\""); + } + + Y_UNIT_TEST(Uint8) { + Test("[DataType;Uint8]","\"1\""); + } + + Y_UNIT_TEST(Int16) { + Test("[DataType;Int16]","\"1\""); + } + + Y_UNIT_TEST(Uint16) { + Test("[DataType;Uint16]","\"1\""); + } + + Y_UNIT_TEST(Int32) { + Test("[DataType;Int32]","\"1\""); + } + + Y_UNIT_TEST(Uint32) { + Test("[DataType;Uint32]","\"1\""); + } + + Y_UNIT_TEST(Int64) { + Test("[DataType;Int64]","\"1\""); + } + + Y_UNIT_TEST(Uint64) { + Test("[DataType;Uint64]","\"1\""); + } + + Y_UNIT_TEST(Float) { + Test("[DataType;Float]","\"1.2\""); + Test("[DataType;Float]","\"-inf\""); + Test("[DataType;Float]","\"nan\""); + } + + Y_UNIT_TEST(Double) { + Test("[DataType;Double]","\"1.2\""); + Test("[DataType;Double]","\"-inf\""); + Test("[DataType;Double]","\"nan\""); + } + + Y_UNIT_TEST(String) { + Test("[DataType;String]","\"foo\""); + Test("[DataType;String]","[\"/w==\"]"); + } + + Y_UNIT_TEST(Utf8) { + Test("[DataType;Utf8]","\"foo\""); + } + + Y_UNIT_TEST(Json) { + Test("[DataType;Json]","\"[]\""); + } + + Y_UNIT_TEST(Yson) { + Test("[DataType;Yson]",R"( + { + "$attributes" = { + "a" = { + "$type" = "int64"; + "$value" = "1" + } + }; + "$value" = { + "foo" = { + "$type" = "string"; + "$value" = "bar" + } + } + })"); + } + + Y_UNIT_TEST(JsonDocument) { + Test("[DataType;JsonDocument]","\"[]\""); + } + + Y_UNIT_TEST(Uuid) { + Test("[DataType;Uuid]","[\"AIQOVZvi1EGnFkRmVUQAAA==\"]"); + } + + Y_UNIT_TEST(DyNumber) { + Test("[DataType;DyNumber]","[\"AoIS\"]"); + } + + Y_UNIT_TEST(Date) { + Test("[DataType;Date]","\"1\""); + } + + Y_UNIT_TEST(Datetime) { + Test("[DataType;Datetime]","\"1\""); + } + + Y_UNIT_TEST(Timestamp) { + Test("[DataType;Timestamp]","\"1\""); + } + + Y_UNIT_TEST(TzDate) { + Test("[DataType;TzDate]","\"2011-04-27,Europe/Moscow\""); + } + + Y_UNIT_TEST(TzDatetime) { + Test("[DataType;TzDatetime]","\"2011-04-27T01:02:03,Europe/Moscow\""); + } + + Y_UNIT_TEST(TzTimestamp) { + Test("[DataType;TzTimestamp]","\"2011-04-27T01:02:03.456789,Europe/Moscow\""); + } + + Y_UNIT_TEST(Interval) { + Test("[DataType;Interval]","\"1\""); + } + + Y_UNIT_TEST(Date32) { + Test("[DataType;Date32]","\"1\""); + } + + Y_UNIT_TEST(Datetime64) { + Test("[DataType;Datetime64]","\"1\""); + } + + Y_UNIT_TEST(Timestamp64) { + Test("[DataType;Timestamp64]","\"1\""); + } + + Y_UNIT_TEST(TzDate32) { + Test("[DataType;TzDate32]","\"2011-04-27,Europe/Moscow\""); + } + + Y_UNIT_TEST(TzDatetime64) { + Test("[DataType;TzDatetime64]","\"2011-04-27T01:02:03,Europe/Moscow\""); + } + + Y_UNIT_TEST(TzTimestamp64) { + Test("[DataType;TzTimestamp64]","\"2011-04-27T01:02:03.456789,Europe/Moscow\""); + } + + Y_UNIT_TEST(Interval64) { + Test("[DataType;Interval64]","\"1\""); + } + + Y_UNIT_TEST(Decimal) { + Test("[DataType;Decimal;\"10\";\"1\"]","\"1.2\""); + Test("[DataType;Decimal;\"10\";\"1\"]","\"-inf\""); + Test("[DataType;Decimal;\"10\";\"1\"]","\"nan\""); + } + + Y_UNIT_TEST(Optional1) { + Test("[OptionalType;[DataType;Int32]]","[]"); + Test("[OptionalType;[DataType;Int32]]","[\"1\"]"); + } + + Y_UNIT_TEST(Optional2) { + Test("[OptionalType;[OptionalType;[DataType;Int32]]]","[]", "#"); + Test("[OptionalType;[OptionalType;[DataType;Int32]]]","[[]]", "[#]"); + Test("[OptionalType;[OptionalType;[DataType;Int32]]]","[[\"1\"]]"); + } + + Y_UNIT_TEST(List1) { + Test("[ListType;[DataType;Int32]]","[]"); + Test("[ListType;[DataType;Int32]]","[\"1\"]"); + Test("[ListType;[DataType;Int32]]","[\"1\";\"2\"]"); + } + + Y_UNIT_TEST(List2) { + Test("[ListType;[ListType;[DataType;Int32]]]","[]"); + Test("[ListType;[ListType;[DataType;Int32]]]","[[];[\"1\"]]"); + Test("[ListType;[ListType;[DataType;Int32]]]","[[\"1\";\"2\";\"3\"];[\"4\";\"5\";\"6\"]]"); + } + + Y_UNIT_TEST(EmptyTuple) { + Test("[TupleType;[]]","[]"); + } + + Y_UNIT_TEST(Tuple) { + Test("[TupleType;[[DataType;Int32];[DataType;String]]]","[\"1\";\"foo\"]"); + } + + Y_UNIT_TEST(EmptyStruct) { + Test("[StructType;[]]","[]"); + } + + Y_UNIT_TEST(Struct) { + Test("[StructType;[[foo;[DataType;Int32]];[bar;[DataType;String]]]]","[\"1\";\"foo\"]"); + } + + Y_UNIT_TEST(Dict) { + Test("[DictType;[DataType;Int32];[DataType;String]]","[]"); + Test("[DictType;[DataType;Int32];[DataType;String]]","[[\"1\";\"foo\"]]"); + Test("[DictType;[DataType;Int32];[DataType;String]]","[[\"1\";\"foo\"];[\"2\";\"bar\"]]"); + } + + Y_UNIT_TEST(Variant) { + Test("[VariantType;[TupleType;[[DataType;Int32];[DataType;String]]]]","[\"0\";\"7\"]"); + Test("[VariantType;[TupleType;[[DataType;Int32];[DataType;String]]]]","[\"1\";\"foo\"]"); + Test("[VariantType;[StructType;[[foo;[DataType;Int32]];[bar;[DataType;String]]]]]","[\"0\";\"7\"]"); + Test("[VariantType;[StructType;[[foo;[DataType;Int32]];[bar;[DataType;String]]]]]","[\"1\";\"foo\"]"); + } + + Y_UNIT_TEST(Tagged) { + Test("[TaggedType;foo;[DataType;Int32]]","\"1\""); + } + + Y_UNIT_TEST(Pg) { + Test("[PgType;\"text\";\"S\"]","#"); + Test("[PgType;\"text\";\"S\"]","\"foo\""); + Test("[PgType;\"bytea\";\"U\"]","[\"EjRWeJoAvN4=\"]"); + } +} + +} 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_response_ut.cpp similarity index 54% rename from ydb/library/yql/public/result_format/ut/yql_result_format_ut.cpp rename to ydb/library/yql/public/result_format/ut/yql_result_format_response_ut.cpp index b0b713e26364..f64762566c06 100644 --- a/ydb/library/yql/public/result_format/ut/yql_result_format_ut.cpp +++ b/ydb/library/yql/public/result_format/ut/yql_result_format_response_ut.cpp @@ -1,4 +1,4 @@ -#include +#include #include @@ -6,347 +6,6 @@ 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(ParseType) { - Y_UNIT_TEST(EmptyVisitor) { - TEmptyTypeVisitor v; - v.OnNull(); - v.OnVoid(); - v.OnEmptyList(); - v.OnEmptyDict(); - v.OnBool(); - v.OnInt8(); - v.OnUint8(); - v.OnInt16(); - v.OnUint16(); - v.OnInt32(); - v.OnUint32(); - v.OnInt64(); - v.OnUint64(); - v.OnFloat(); - v.OnDouble(); - v.OnString(); - v.OnUtf8(); - v.OnYson(); - v.OnJson(); - v.OnJsonDocument(); - v.OnUuid(); - v.OnDyNumber(); - v.OnDate(); - v.OnDatetime(); - v.OnTimestamp(); - v.OnTzDate(); - v.OnTzDatetime(); - v.OnTzTimestamp(); - v.OnInterval(); - v.OnDate32(); - v.OnDatetime64(); - v.OnTimestamp64(); - v.OnTzDate32(); - v.OnTzDatetime64(); - v.OnTzTimestamp64(); - v.OnInterval64(); - v.OnDecimal(10, 1); - v.OnBeginOptional(); - v.OnEndOptional(); - v.OnBeginList(); - v.OnEndList(); - v.OnBeginTuple(); - v.OnTupleItem(); - v.OnEndTuple(); - v.OnBeginStruct(); - v.OnStructItem("foo"); - v.OnEndStruct(); - v.OnBeginDict(); - v.OnDictKey(); - v.OnDictPayload(); - v.OnEndDict(); - v.OnBeginVariant(); - v.OnEndVariant(); - v.OnBeginTagged("foo"); - v.OnEndTagged(); - v.OnPgType("int4", "N"); - } - - Y_UNIT_TEST(ThrowingVisitor) { - 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]"); - } -} - Y_UNIT_TEST_SUITE(ParseResponse) { Y_UNIT_TEST(Empty) { auto response = NYT::NodeFromYsonString("[]"); diff --git a/ydb/library/yql/public/result_format/ut/yql_result_format_type_ut.cpp b/ydb/library/yql/public/result_format/ut/yql_result_format_type_ut.cpp new file mode 100644 index 000000000000..3df841814175 --- /dev/null +++ b/ydb/library/yql/public/result_format/ut/yql_result_format_type_ut.cpp @@ -0,0 +1,352 @@ +#include + +#include + +#include + +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(ParseType) { + Y_UNIT_TEST(EmptyVisitor) { + TEmptyTypeVisitor v; + v.OnNull(); + v.OnVoid(); + v.OnEmptyList(); + v.OnEmptyDict(); + v.OnBool(); + v.OnInt8(); + v.OnUint8(); + v.OnInt16(); + v.OnUint16(); + v.OnInt32(); + v.OnUint32(); + v.OnInt64(); + v.OnUint64(); + v.OnFloat(); + v.OnDouble(); + v.OnString(); + v.OnUtf8(); + v.OnYson(); + v.OnJson(); + v.OnJsonDocument(); + v.OnUuid(); + v.OnDyNumber(); + v.OnDate(); + v.OnDatetime(); + v.OnTimestamp(); + v.OnTzDate(); + v.OnTzDatetime(); + v.OnTzTimestamp(); + v.OnInterval(); + v.OnDate32(); + v.OnDatetime64(); + v.OnTimestamp64(); + v.OnTzDate32(); + v.OnTzDatetime64(); + v.OnTzTimestamp64(); + v.OnInterval64(); + v.OnDecimal(10, 1); + v.OnBeginOptional(); + v.OnEndOptional(); + v.OnBeginList(); + v.OnEndList(); + v.OnBeginTuple(); + v.OnTupleItem(); + v.OnEndTuple(); + v.OnBeginStruct(); + v.OnStructItem("foo"); + v.OnEndStruct(); + v.OnBeginDict(); + v.OnDictKey(); + v.OnDictPayload(); + v.OnEndDict(); + v.OnBeginVariant(); + v.OnEndVariant(); + v.OnBeginTagged("foo"); + v.OnEndTagged(); + v.OnPg("int4", "N"); + } + + Y_UNIT_TEST(ThrowingVisitor) { + 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.OnPg("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(Pg) { + Test("[PgType;int4;N]"); + } +} + +} + + diff --git a/ydb/library/yql/public/result_format/ya.make b/ydb/library/yql/public/result_format/ya.make index 192d9dfa5d89..ceb410bb767a 100644 --- a/ydb/library/yql/public/result_format/ya.make +++ b/ydb/library/yql/public/result_format/ya.make @@ -1,12 +1,19 @@ LIBRARY() SRCS( - yql_result_format.cpp + yql_result_format_response.cpp + yql_result_format_type.cpp + yql_result_format_data.cpp + yql_codec_results.cpp + yql_restricted_yson.cpp ) PEERDIR( + library/cpp/yson library/cpp/yson/node + library/cpp/string_utils/base64 ydb/library/yql/public/issue + ydb/library/yql/utils ) END() diff --git a/ydb/library/yql/providers/common/codec/yql_codec_results.cpp b/ydb/library/yql/public/result_format/yql_codec_results.cpp similarity index 96% rename from ydb/library/yql/providers/common/codec/yql_codec_results.cpp rename to ydb/library/yql/public/result_format/yql_codec_results.cpp index 96c7d784cab8..72e49f13766c 100644 --- a/ydb/library/yql/providers/common/codec/yql_codec_results.cpp +++ b/ydb/library/yql/public/result_format/yql_codec_results.cpp @@ -5,7 +5,7 @@ #include namespace NYql { -namespace NCommon { +namespace NResult { constexpr TStringBuf TYsonResultWriter::VoidString; diff --git a/ydb/library/yql/providers/common/codec/yql_codec_results.h b/ydb/library/yql/public/result_format/yql_codec_results.h similarity index 99% rename from ydb/library/yql/providers/common/codec/yql_codec_results.h rename to ydb/library/yql/public/result_format/yql_codec_results.h index e9cd9dc0f8f3..3fae20cf8330 100644 --- a/ydb/library/yql/providers/common/codec/yql_codec_results.h +++ b/ydb/library/yql/public/result_format/yql_codec_results.h @@ -5,7 +5,7 @@ #include namespace NYql { -namespace NCommon { +namespace NResult { // we should not write numbers as numbers ever // write numbers as strings except Yson value where we use restricted dialect diff --git a/ydb/library/yql/providers/common/codec/yql_restricted_yson.cpp b/ydb/library/yql/public/result_format/yql_restricted_yson.cpp similarity index 97% rename from ydb/library/yql/providers/common/codec/yql_restricted_yson.cpp rename to ydb/library/yql/public/result_format/yql_restricted_yson.cpp index 08b4521748d5..ead7124f7481 100644 --- a/ydb/library/yql/providers/common/codec/yql_restricted_yson.cpp +++ b/ydb/library/yql/public/result_format/yql_restricted_yson.cpp @@ -13,7 +13,7 @@ #include namespace NYql { -namespace NCommon { +namespace NResult { namespace { class TRestrictedYsonFormatter : public NYson::TYsonConsumerBase { @@ -314,13 +314,16 @@ TString EncodeRestrictedYson(const NYT::TNode& node, NYson::EYsonFormat format) return stream.Str(); } -TString DecodeRestrictedYson(const TStringBuf& yson, NYson::EYsonFormat format) { +TString DecodeRestrictedYson(const NYT::TNode& node, NYson::EYsonFormat format) { TStringStream stream; NYson::TYsonWriter writer(&stream, format); - auto node = NYT::NodeFromYsonString(yson); DecodeRestrictedYson(node, writer); return stream.Str(); } +TString DecodeRestrictedYson(const TStringBuf& yson, NYson::EYsonFormat format) { + return DecodeRestrictedYson(NYT::NodeFromYsonString(yson), format); +} + } } diff --git a/ydb/library/yql/providers/common/codec/yql_restricted_yson.h b/ydb/library/yql/public/result_format/yql_restricted_yson.h similarity index 78% rename from ydb/library/yql/providers/common/codec/yql_restricted_yson.h rename to ydb/library/yql/public/result_format/yql_restricted_yson.h index 0d0f7568d610..ba88c4121a79 100644 --- a/ydb/library/yql/providers/common/codec/yql_restricted_yson.h +++ b/ydb/library/yql/public/result_format/yql_restricted_yson.h @@ -10,7 +10,7 @@ namespace NYT { } namespace NYql { -namespace NCommon { +namespace NResult { void EncodeRestrictedYson( TYsonResultWriter& writer, @@ -24,5 +24,9 @@ TString DecodeRestrictedYson( const TStringBuf& yson, NYson::EYsonFormat format = NYson::EYsonFormat::Binary); +TString DecodeRestrictedYson( + const NYT::TNode& node, + NYson::EYsonFormat format = NYson::EYsonFormat::Binary); + } } diff --git a/ydb/library/yql/public/result_format/yql_result_format_common.h b/ydb/library/yql/public/result_format/yql_result_format_common.h new file mode 100644 index 000000000000..875104d93ff5 --- /dev/null +++ b/ydb/library/yql/public/result_format/yql_result_format_common.h @@ -0,0 +1,8 @@ +#pragma once +#include + +namespace NYql::NResult { + +class TUnsupportedException : public yexception {}; + +} diff --git a/ydb/library/yql/public/result_format/yql_result_format_data.cpp b/ydb/library/yql/public/result_format/yql_result_format_data.cpp new file mode 100644 index 000000000000..eace0e9c66e3 --- /dev/null +++ b/ydb/library/yql/public/result_format/yql_result_format_data.cpp @@ -0,0 +1,1164 @@ +#include "yql_result_format_data.h" +#include "yql_result_format_type.h" +#include "yql_result_format_impl.h" + +#include "yql_restricted_yson.h" +#include +#include + +#include +#include +#include + + +namespace NYql::NResult { + +class IDataProcessor { +public: + virtual ~IDataProcessor() = default; + virtual void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) = 0; +}; + +class TVoidProcessor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsString()); + CHECK(dataNode.AsString() == "Void"); + visitor.OnVoid(); + } +}; + +class TNullProcessor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsEntity()); + visitor.OnNull(); + } +}; + +class TEmptyListProcessor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsList() && dataNode.AsList().size() == 0); + visitor.OnEmptyList(); + } +}; + +class TEmptyDictProcessor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsList() && dataNode.AsList().size() == 0); + visitor.OnEmptyDict(); + } +}; + +template +class TIntegerProcessor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsString()); + (visitor.*Func)(FromString(dataNode.AsString())); + } +}; + +template +class TFloatingProcessor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsString()); + (visitor.*Func)(Conv(dataNode.AsString())); + } +}; + +class TBoolProcessor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsBool()); + visitor.OnBool(dataNode.AsBool()); + } +}; + +template +class TStringProcessor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsString() || + dataNode.IsList() && dataNode.AsList().size() == 1 && dataNode.AsList()[0].IsString()); + if (dataNode.IsString()) { + (visitor.*Func)(dataNode.AsString(), true); + } else { + (visitor.*Func)(Base64Decode(dataNode.AsList()[0].AsString()), false); + } + } +}; + +template +class TUtf8Processor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsString()); + (visitor.*Func)(dataNode.AsString()); + } +}; + +class TYsonProcessor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + auto str = DecodeRestrictedYson(dataNode); + visitor.OnYson(str, IsUtf8(str)); + } +}; + +class TOptionalProcessor : public IDataProcessor { +public: + TOptionalProcessor(std::unique_ptr&& inner) + : Inner(std::move(inner)) + {} + + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsEntity() || dataNode.IsList() && dataNode.AsList().size() <= 1); + visitor.OnBeginOptional(); + if (dataNode.IsEntity() || dataNode.AsList().empty()) { + visitor.OnEmptyOptional(); + } else { + visitor.OnBeforeOptionalItem(); + Inner->Process(dataNode.AsList()[0], visitor); + visitor.OnAfterOptionalItem(); + } + + visitor.OnEndOptional(); + } + +private: + const std::unique_ptr Inner; +}; + +class TListProcessor : public IDataProcessor { +public: + TListProcessor(std::unique_ptr&& inner) + : Inner(std::move(inner)) + {} + + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsList()); + visitor.OnBeginList(); + for (const auto& item : dataNode.AsList()) { + visitor.OnBeforeListItem(); + Inner->Process(item, visitor); + visitor.OnAfterListItem(); + } + + visitor.OnEndList(); + } + +private: + const std::unique_ptr Inner; +}; + +class TTupleProcessor : public IDataProcessor { +public: + TTupleProcessor(TVector>&& inners) + : Inners(std::move(inners)) + {} + + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsList()); + visitor.OnBeginTuple(); + CHECK(dataNode.AsList().size() == Inners.size()); + for (ui32 i = 0; i < Inners.size(); ++i) { + visitor.OnBeforeTupleItem(); + Inners[i]->Process(dataNode.AsList()[i], visitor); + visitor.OnAfterTupleItem(); + } + + visitor.OnEndTuple(); + } + +private: + const TVector> Inners; +}; + +class TStructProcessor : public IDataProcessor { +public: + TStructProcessor(TVector>&& inners) + : Inners(std::move(inners)) + {} + + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsList()); + visitor.OnBeginStruct(); + CHECK(dataNode.AsList().size() == Inners.size()); + for (ui32 i = 0; i < Inners.size(); ++i) { + visitor.OnBeforeStructItem(); + Inners[i]->Process(dataNode.AsList()[i], visitor); + visitor.OnAfterStructItem(); + } + + visitor.OnEndStruct(); + } + +private: + const TVector> Inners; +}; + +class TDictProcessor : public IDataProcessor { +public: + TDictProcessor(std::unique_ptr&& innerKey, std::unique_ptr&& innerPayload) + : InnerKey(std::move(innerKey)) + , InnerPayload(std::move(innerPayload)) + {} + + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsList()); + visitor.OnBeginDict(); + for (const auto& item : dataNode.AsList()) { + CHECK(item.IsList() && item.AsList().size() == 2); + visitor.OnBeforeDictItem(); + visitor.OnBeforeDictKey(); + InnerKey->Process(item.AsList()[0], visitor); + visitor.OnAfterDictKey(); + visitor.OnBeforeDictPayload(); + InnerPayload->Process(item.AsList()[1], visitor); + visitor.OnAfterDictPayload(); + visitor.OnAfterDictItem(); + } + + visitor.OnEndDict(); + } + +private: + const std::unique_ptr InnerKey; + const std::unique_ptr InnerPayload; +}; + +class TVariantProcessor : public IDataProcessor { +public: + TVariantProcessor(TVector>&& inners) + : Inners(std::move(inners)) + {} + + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsList() && dataNode.AsList().size() == 2); + CHECK(dataNode.AsList()[0].IsString()); + ui32 index = FromString(dataNode.AsList()[0].AsString()); + CHECK(index < Inners.size()); + visitor.OnBeginVariant(index); + Inners[index]->Process(dataNode.AsList()[1], visitor); + visitor.OnEndVariant(); + } + +private: + const TVector> Inners; +}; + +class TPgProcessor : public IDataProcessor { +public: + void Process(const NYT::TNode& dataNode, IDataVisitor& visitor) final { + CHECK(dataNode.IsEntity() || dataNode.IsString() || + dataNode.IsList() && dataNode.AsList().size() == 1 && dataNode.AsList()[0].IsString()); + if (dataNode.IsEntity()) { + visitor.OnPg(Nothing(), true); + } else if (dataNode.IsString()) { + visitor.OnPg(dataNode.AsString(), true); + } else { + visitor.OnPg(Base64Decode(dataNode.AsList()[0].AsString()), false); + } + } +}; + +class TDataProcessorBuilder : public TThrowingTypeVisitor { +public: + TDataProcessorBuilder() { + IsVariant.push_back(false); + } + + IDataProcessor& GetResult() { + CHECK(Stack.size() == 1); + return *Stack.front(); + } + + void OnVoid() final { + Stack.push_back(std::make_unique()); + } + + void OnNull() final { + Stack.push_back(std::make_unique()); + } + + void OnEmptyList() final { + Stack.push_back(std::make_unique()); + } + + void OnEmptyDict() final { + Stack.push_back(std::make_unique()); + } + + void OnBool() final { + Stack.push_back(std::make_unique()); + } + + void OnInt8() final { + Stack.push_back(std::make_unique>()); + } + + void OnUint8() final { + Stack.push_back(std::make_unique>()); + } + + void OnInt16() final { + Stack.push_back(std::make_unique>()); + } + + void OnUint16() final { + Stack.push_back(std::make_unique>()); + } + + void OnInt32() final { + Stack.push_back(std::make_unique>()); + } + + void OnUint32() final { + Stack.push_back(std::make_unique>()); + } + + void OnInt64() final { + Stack.push_back(std::make_unique>()); + } + + void OnUint64() final { + Stack.push_back(std::make_unique>()); + } + + void OnFloat() final { + Stack.push_back(std::make_unique>()); + } + + void OnDouble() final { + Stack.push_back(std::make_unique>()); + } + + void OnString() final { + Stack.push_back(std::make_unique>()); + } + + void OnUtf8() final { + Stack.push_back(std::make_unique>()); + } + + void OnYson() final { + Stack.push_back(std::make_unique()); + } + + void OnJson() final { + Stack.push_back(std::make_unique>()); + } + + void OnJsonDocument() final { + Stack.push_back(std::make_unique>()); + } + + void OnUuid() final { + Stack.push_back(std::make_unique>()); + } + + void OnDyNumber() final { + Stack.push_back(std::make_unique>()); + } + + void OnDate() final { + Stack.push_back(std::make_unique>()); + } + + void OnDatetime() final { + Stack.push_back(std::make_unique>()); + } + + void OnTimestamp() final { + Stack.push_back(std::make_unique>()); + } + + void OnTzDate() final { + Stack.push_back(std::make_unique>()); + } + + void OnTzDatetime() final { + Stack.push_back(std::make_unique>()); + } + + void OnTzTimestamp() final { + Stack.push_back(std::make_unique>()); + } + + void OnInterval() final { + Stack.push_back(std::make_unique>()); + } + + void OnDate32() final { + Stack.push_back(std::make_unique>()); + } + + void OnDatetime64() final { + Stack.push_back(std::make_unique>()); + } + + void OnTimestamp64() final { + Stack.push_back(std::make_unique>()); + } + + void OnTzDate32() final { + Stack.push_back(std::make_unique>()); + } + + void OnTzDatetime64() final { + Stack.push_back(std::make_unique>()); + } + + void OnTzTimestamp64() final { + Stack.push_back(std::make_unique>()); + } + + void OnInterval64() final { + Stack.push_back(std::make_unique>()); + } + + void OnDecimal(ui32 precision, ui32 scale) final { + Y_UNUSED(precision); + Y_UNUSED(scale); + Stack.push_back(std::make_unique>()); + } + + void OnBeginOptional() final { + } + + void OnEndOptional() final { + auto inner = Pop(); + Stack.push_back(std::make_unique(std::move(inner))); + } + + void OnBeginList() final { + } + + void OnEndList() final { + auto inner = Pop(); + Stack.push_back(std::make_unique(std::move(inner))); + } + + void OnBeginTuple() final { + IsVariant.push_back(false); + Args.push_back(0); + } + + void OnTupleItem() final { + Args.back() += 1; + } + + void OnEndTuple() final { + const ui32 width = Args.back(); + auto inners = Pop(width); + if (!IsVariant[IsVariant.size() - 2]) { + Stack.push_back(std::make_unique(std::move(inners))); + } else { + Stack.push_back(std::make_unique(std::move(inners))); + } + + Args.pop_back(); + IsVariant.pop_back(); + } + + void OnBeginStruct() final { + IsVariant.push_back(false); + Args.push_back(0); + } + + void OnStructItem(TStringBuf member) final { + Y_UNUSED(member); + Args.back() += 1; + } + + void OnEndStruct() final { + const ui32 width = Args.back(); + auto inners = Pop(width); + if (!IsVariant[IsVariant.size() - 2]) { + Stack.push_back(std::make_unique(std::move(inners))); + } else { + Stack.push_back(std::make_unique(std::move(inners))); + } + + Args.pop_back(); + IsVariant.pop_back(); + } + + void OnBeginDict() final { + } + + void OnDictKey() final { + } + + void OnDictPayload() final { + } + + void OnEndDict() final { + auto innerPayload = Pop(); + auto innerKey = Pop(); + Stack.push_back(std::make_unique(std::move(innerKey), std::move(innerPayload))); + } + + void OnBeginVariant() { + IsVariant.push_back(true); + } + + void OnEndVariant() { + IsVariant.pop_back(); + } + + void OnBeginTagged(TStringBuf tag) { + Y_UNUSED(tag); + } + + void OnEndTagged() { + } + + void OnPg(TStringBuf name, TStringBuf category) final { + Y_UNUSED(name); + Y_UNUSED(category); + Stack.push_back(std::make_unique()); + } + +private: + std::unique_ptr Pop() { + CHECK(!Stack.empty()); + auto res = std::move(Stack.back()); + Stack.pop_back(); + return res; + } + + TVector> Pop(ui32 width) { + CHECK(Stack.size() >= width); + TVector> res; + res.reserve(width); + for (ui32 i = 0; i < width; ++i) { + res.push_back(Pop()); + } + + Reverse(res.begin(), res.end()); + return res; + } + +private: + TVector> Stack; + TVector Args; + TVector IsVariant; +}; + +void ParseData(const NYT::TNode& typeNode, const NYT::TNode& dataNode, IDataVisitor& visitor) { + TDataProcessorBuilder builder; + ParseType(typeNode, builder); + builder.GetResult().Process(dataNode, visitor); +} + +TDataBuilder::TDataBuilder() { + Stack.push_back(&Root); +} + +const NYT::TNode& TDataBuilder::GetResult() const { + CHECK(Stack.size() == 1); + return Root; +} + +void TDataBuilder::OnVoid() { + Top() = "Void"; +} + +void TDataBuilder::OnNull() { + Top() = NYT::TNode::CreateEntity(); +} + +void TDataBuilder::OnEmptyList() { + Top() = NYT::TNode::CreateList(); +} + +void TDataBuilder::OnEmptyDict() { + Top() = NYT::TNode::CreateList(); +} + +void TDataBuilder::OnBool(bool value) { + Top() = value; +} + +void TDataBuilder::OnInt8(i8 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnUint8(ui8 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnInt16(i16 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnUint16(ui16 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnInt32(i32 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnUint32(ui32 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnInt64(i64 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnUint64(ui64 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnFloat(float value) { + Top() = FloatToString(value); +} + +void TDataBuilder::OnDouble(double value) { + Top() = FloatToString(value); +} + +void TDataBuilder::OnString(TStringBuf value, bool isUtf8) { + if (isUtf8) { + Top() = value; + } else { + Top() = NYT::TNode().Add(Base64Encode(value)); + } +} + +void TDataBuilder::OnUtf8(TStringBuf value) { + Top() = value; +} + +void TDataBuilder::OnYson(TStringBuf value, bool isUtf8) { + Y_UNUSED(isUtf8); + NYT::TNodeBuilder builder(&Top()); + TYsonResultWriter writer(builder); + EncodeRestrictedYson(writer, value); +} + +void TDataBuilder::OnJson(TStringBuf value) { + Top() = value; +} + +void TDataBuilder::OnJsonDocument(TStringBuf value) { + Top() = value; +} + +void TDataBuilder::OnUuid(TStringBuf value, bool isUtf8) { + OnString(value, isUtf8); +} + +void TDataBuilder::OnDyNumber(TStringBuf value, bool isUtf8) { + OnString(value, isUtf8); +} + +void TDataBuilder::OnDate(ui16 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnDatetime(ui32 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnTimestamp(ui64 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnTzDate(TStringBuf value) { + Top() = value; +} + +void TDataBuilder::OnTzDatetime(TStringBuf value) { + Top() = value; +} + +void TDataBuilder::OnTzTimestamp(TStringBuf value) { + Top() = value; +} + +void TDataBuilder::OnInterval(i64 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnDate32(i32 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnDatetime64(i64 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnTimestamp64(i64 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnTzDate32(TStringBuf value) { + Top() = value; +} + +void TDataBuilder::OnTzDatetime64(TStringBuf value) { + Top() = value; +} + +void TDataBuilder::OnTzTimestamp64(TStringBuf value) { + Top() = value; +} + +void TDataBuilder::OnInterval64(i64 value) { + Top() = ToString(value); +} + +void TDataBuilder::OnDecimal(TStringBuf value) { + Top() = value; +} + +void TDataBuilder::OnBeginOptional() { + Top() = NYT::TNode::CreateList(); +} + +void TDataBuilder::OnBeforeOptionalItem() { + Top().Add(); + Push(&Top().AsList()[0]); +} + +void TDataBuilder::OnAfterOptionalItem() { + Pop(); +} + +void TDataBuilder::OnEmptyOptional() { +} + +void TDataBuilder::OnEndOptional() { +} + +void TDataBuilder::OnBeginList() { + Top() = NYT::TNode::CreateList(); +} + +void TDataBuilder::OnBeforeListItem() { + Top().Add(); + Push(&Top().AsList().back()); +} + +void TDataBuilder::OnAfterListItem() { + Pop(); +} + +void TDataBuilder::OnEndList() { +} + +void TDataBuilder::OnBeginTuple() { + Top() = NYT::TNode::CreateList(); +} + +void TDataBuilder::OnBeforeTupleItem() { + Top().Add(); + Push(&Top().AsList().back()); +} + +void TDataBuilder::OnAfterTupleItem() { + Pop(); +} + +void TDataBuilder::OnEndTuple() { +} + +void TDataBuilder::OnBeginStruct() { + Top() = NYT::TNode::CreateList(); +} + +void TDataBuilder::OnBeforeStructItem() { + Top().Add(); + Push(&Top().AsList().back()); +} + +void TDataBuilder::OnAfterStructItem() { + Pop(); +} + +void TDataBuilder::OnEndStruct() { +} + +void TDataBuilder::OnBeginDict() { + Top() = NYT::TNode::CreateList(); +} + +void TDataBuilder::OnBeforeDictItem() { + Top().Add(); + Push(&Top().AsList().back()); +} + +void TDataBuilder::OnBeforeDictKey() { + Top().Add(); + Push(&Top().AsList().back()); +} + +void TDataBuilder::OnAfterDictKey() { + Pop(); +} + +void TDataBuilder::OnBeforeDictPayload() { + Top().Add(); + Push(&Top().AsList().back()); +} + +void TDataBuilder::OnAfterDictPayload() { + Pop(); +} + +void TDataBuilder::OnAfterDictItem() { + Pop(); +} + +void TDataBuilder::OnEndDict() { +} + +void TDataBuilder::OnBeginVariant(ui32 index) { + Top() = NYT::TNode::CreateList(); + Top().Add(ToString(index)); + Top().Add(); + Push(&Top().AsList().back()); +} + +void TDataBuilder::OnEndVariant() { + Pop(); +} + +void TDataBuilder::OnPg(TMaybe value, bool isUtf8) { + if (!value.Defined()) { + Top() = NYT::TNode::CreateEntity(); + } else if (isUtf8) { + Top() = *value; + } else { + Top() = NYT::TNode().Add(Base64Encode(*value)); + } +} + +NYT::TNode& TDataBuilder::Top() { + return *Stack.back(); +} + +void TDataBuilder::Push(NYT::TNode* value) { + Stack.push_back(value); +} + +void TDataBuilder::Pop() { + Stack.pop_back(); +} + +void TSameActionDataVisitor::OnVoid() { + Do(); +} + +void TSameActionDataVisitor::OnNull() { + Do(); +} + +void TSameActionDataVisitor::OnEmptyList() { + Do(); +} + +void TSameActionDataVisitor::OnEmptyDict() { + Do(); +} + +void TSameActionDataVisitor::OnBool(bool value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnInt8(i8 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnUint8(ui8 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnInt16(i16 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnUint16(ui16 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnInt32(i32 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnUint32(ui32 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnInt64(i64 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnUint64(ui64 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnFloat(float value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnDouble(double value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnString(TStringBuf value, bool isUtf8) { + Y_UNUSED(value); + Y_UNUSED(isUtf8); + Do(); +} + +void TSameActionDataVisitor::OnUtf8(TStringBuf value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnYson(TStringBuf value, bool isUtf8) { + Y_UNUSED(value); + Y_UNUSED(isUtf8); + Do(); +} + +void TSameActionDataVisitor::OnJson(TStringBuf value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnJsonDocument(TStringBuf value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnUuid(TStringBuf value, bool isUtf8) { + Y_UNUSED(value); + Y_UNUSED(isUtf8); + Do(); +} + +void TSameActionDataVisitor::OnDyNumber(TStringBuf value, bool isUtf8) { + Y_UNUSED(value); + Y_UNUSED(isUtf8); + Do(); +} + +void TSameActionDataVisitor::OnDate(ui16 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnDatetime(ui32 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnTimestamp(ui64 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnTzDate(TStringBuf value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnTzDatetime(TStringBuf value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnTzTimestamp(TStringBuf value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnInterval(i64 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnDate32(i32 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnDatetime64(i64 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnTimestamp64(i64 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnTzDate32(TStringBuf value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnTzDatetime64(TStringBuf value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnTzTimestamp64(TStringBuf value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnInterval64(i64 value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnDecimal(TStringBuf value) { + Y_UNUSED(value); + Do(); +} + +void TSameActionDataVisitor::OnBeginOptional() { + Do(); +} + +void TSameActionDataVisitor::OnBeforeOptionalItem() { + Do(); +} + +void TSameActionDataVisitor::OnAfterOptionalItem() { + Do(); +} + +void TSameActionDataVisitor::OnEmptyOptional() { + Do(); +} + +void TSameActionDataVisitor::OnEndOptional() { + Do(); +} + +void TSameActionDataVisitor::OnBeginList() { + Do(); +} + +void TSameActionDataVisitor::OnBeforeListItem() { + Do(); +} + +void TSameActionDataVisitor::OnAfterListItem() { + Do(); +} + +void TSameActionDataVisitor::OnEndList() { + Do(); +} + +void TSameActionDataVisitor::OnBeginTuple() { + Do(); +} + +void TSameActionDataVisitor::OnBeforeTupleItem() { + Do(); +} + +void TSameActionDataVisitor::OnAfterTupleItem() { + Do(); +} + +void TSameActionDataVisitor::OnEndTuple() { + Do(); +} + +void TSameActionDataVisitor::OnBeginStruct() { + Do(); +} + +void TSameActionDataVisitor::OnBeforeStructItem() { + Do(); +} + +void TSameActionDataVisitor::OnAfterStructItem() { + Do(); +} + +void TSameActionDataVisitor::OnEndStruct() { + Do(); +} + +void TSameActionDataVisitor::OnBeginDict() { + Do(); +} + +void TSameActionDataVisitor::OnBeforeDictItem() { + Do(); +} + +void TSameActionDataVisitor::OnBeforeDictKey() { + Do(); +} + +void TSameActionDataVisitor::OnAfterDictKey() { + Do(); +} + +void TSameActionDataVisitor::OnBeforeDictPayload() { + Do(); +} + +void TSameActionDataVisitor::OnAfterDictPayload() { + Do(); +} + +void TSameActionDataVisitor::OnAfterDictItem() { + Do(); +} + +void TSameActionDataVisitor::OnEndDict() { + Do(); +} + +void TSameActionDataVisitor::OnBeginVariant(ui32 index) { + Y_UNUSED(index); + Do(); +} + +void TSameActionDataVisitor::OnEndVariant() { + Do(); +} + +void TSameActionDataVisitor::OnPg(TMaybe value, bool isUtf8) { + Y_UNUSED(value); + Y_UNUSED(isUtf8); + Do(); +} + +void TThrowingDataVisitor::Do() { + UNEXPECTED; +} + +void TEmptyDataVisitor::Do() { +} + +} diff --git a/ydb/library/yql/public/result_format/yql_result_format_data.h b/ydb/library/yql/public/result_format/yql_result_format_data.h new file mode 100644 index 000000000000..58290a5c4108 --- /dev/null +++ b/ydb/library/yql/public/result_format/yql_result_format_data.h @@ -0,0 +1,245 @@ +#pragma once + +#include "yql_result_format_common.h" + +#include + +namespace NYql::NResult { + +class IDataVisitor { +public: + virtual ~IDataVisitor() = default; + + virtual void OnVoid() = 0; + virtual void OnNull() = 0; + virtual void OnEmptyList() = 0; + virtual void OnEmptyDict() = 0; + virtual void OnBool(bool value) = 0; + virtual void OnInt8(i8 value) = 0; + virtual void OnUint8(ui8 value) = 0; + virtual void OnInt16(i16 value) = 0; + virtual void OnUint16(ui16 value) = 0; + virtual void OnInt32(i32 value) = 0; + virtual void OnUint32(ui32 value) = 0; + virtual void OnInt64(i64 value) = 0; + virtual void OnUint64(ui64 value) = 0; + virtual void OnFloat(float value) = 0; + virtual void OnDouble(double value) = 0; + virtual void OnString(TStringBuf value, bool isUtf8) = 0; + virtual void OnUtf8(TStringBuf value) = 0; + virtual void OnYson(TStringBuf value, bool isUtf8) = 0; + virtual void OnJson(TStringBuf value) = 0; + virtual void OnJsonDocument(TStringBuf value) = 0; + virtual void OnUuid(TStringBuf value, bool isUtf8) = 0; + virtual void OnDyNumber(TStringBuf value, bool isUtf8) = 0; + virtual void OnDate(ui16 value) = 0; + virtual void OnDatetime(ui32 value) = 0; + virtual void OnTimestamp(ui64 value) = 0; + virtual void OnTzDate(TStringBuf value) = 0; + virtual void OnTzDatetime(TStringBuf value) = 0; + virtual void OnTzTimestamp(TStringBuf value) = 0; + virtual void OnInterval(i64 value) = 0; + virtual void OnDate32(i32 value) = 0; + virtual void OnDatetime64(i64 value) = 0; + virtual void OnTimestamp64(i64 value) = 0; + virtual void OnTzDate32(TStringBuf value) = 0; + virtual void OnTzDatetime64(TStringBuf value) = 0; + virtual void OnTzTimestamp64(TStringBuf value) = 0; + virtual void OnInterval64(i64 value) = 0; + virtual void OnDecimal(TStringBuf value) = 0; + virtual void OnBeginOptional() = 0; + virtual void OnEmptyOptional() = 0; + virtual void OnBeforeOptionalItem() = 0; + virtual void OnAfterOptionalItem() = 0; + virtual void OnEndOptional() = 0; + virtual void OnBeginList() = 0; + virtual void OnBeforeListItem() = 0; + virtual void OnAfterListItem() = 0; + virtual void OnEndList() = 0; + virtual void OnBeginTuple() = 0; + virtual void OnBeforeTupleItem() = 0; + virtual void OnAfterTupleItem() = 0; + virtual void OnEndTuple() = 0; + virtual void OnBeginStruct() = 0; + virtual void OnBeforeStructItem() = 0; + virtual void OnAfterStructItem() = 0; + virtual void OnEndStruct() = 0; + virtual void OnBeginDict() = 0; + virtual void OnBeforeDictItem() = 0; + virtual void OnBeforeDictKey() = 0; + virtual void OnAfterDictKey() = 0; + virtual void OnBeforeDictPayload() = 0; + virtual void OnAfterDictPayload() = 0; + virtual void OnAfterDictItem() = 0; + virtual void OnEndDict() = 0; + virtual void OnBeginVariant(ui32 index) = 0; + virtual void OnEndVariant() = 0; + virtual void OnPg(TMaybe value, bool isUtf8) = 0; +}; + +class TSameActionDataVisitor : public IDataVisitor { +public: + void OnVoid() override; + void OnNull() override; + void OnEmptyList() override; + void OnEmptyDict() override; + void OnBool(bool value) override; + void OnInt8(i8 value) override; + void OnUint8(ui8 value) override; + void OnInt16(i16 value) override; + void OnUint16(ui16 value) override; + void OnInt32(i32 value) override; + void OnUint32(ui32 value) override; + void OnInt64(i64 value) override; + void OnUint64(ui64 value) override; + void OnFloat(float value) override; + void OnDouble(double value) override; + void OnString(TStringBuf value, bool isUtf8) override; + void OnUtf8(TStringBuf value) override; + void OnYson(TStringBuf value, bool isUtf8) override; + void OnJson(TStringBuf value) override; + void OnJsonDocument(TStringBuf value) override; + void OnUuid(TStringBuf value, bool isUtf8) override; + void OnDyNumber(TStringBuf value, bool isUtf8) override; + void OnDate(ui16 value) override; + void OnDatetime(ui32 value) override; + void OnTimestamp(ui64 value) override; + void OnTzDate(TStringBuf value) override; + void OnTzDatetime(TStringBuf value) override; + void OnTzTimestamp(TStringBuf value) override; + void OnInterval(i64 value) override; + void OnDate32(i32 value) override; + void OnDatetime64(i64 value) override; + void OnTimestamp64(i64 value) override; + void OnTzDate32(TStringBuf value) override; + void OnTzDatetime64(TStringBuf value) override; + void OnTzTimestamp64(TStringBuf value) override; + void OnInterval64(i64 value) override; + void OnDecimal(TStringBuf value) override; + void OnBeginOptional() override; + void OnBeforeOptionalItem() override; + void OnAfterOptionalItem() override; + void OnEmptyOptional() override; + void OnEndOptional() override; + void OnBeginList() override; + void OnBeforeListItem() override; + void OnAfterListItem() override; + void OnEndList() override; + void OnBeginTuple() override; + void OnBeforeTupleItem() override; + void OnAfterTupleItem() override; + void OnEndTuple() override; + void OnBeginStruct() override; + void OnBeforeStructItem() override; + void OnAfterStructItem() override; + void OnEndStruct() override; + void OnBeginDict() override; + void OnBeforeDictItem() override; + void OnBeforeDictKey() override; + void OnAfterDictKey() override; + void OnBeforeDictPayload() override; + void OnAfterDictPayload() override; + void OnAfterDictItem() override; + void OnEndDict() override; + void OnBeginVariant(ui32 index) override; + void OnEndVariant() override; + void OnPg(TMaybe value, bool isUtf8) override; + +public: + virtual void Do() = 0; +}; + +class TThrowingDataVisitor : public TSameActionDataVisitor { +public: + void Do() final; +}; + +class TEmptyDataVisitor : public TSameActionDataVisitor { +public: + void Do() final; +}; + +void ParseData(const NYT::TNode& typeNode, const NYT::TNode& dataNode, IDataVisitor& visitor); + +class TDataBuilder : public IDataVisitor { +public: + TDataBuilder(); + const NYT::TNode& GetResult() const; + + void OnVoid() final; + void OnNull() final; + void OnEmptyList() final; + void OnEmptyDict() final; + void OnBool(bool value) final; + void OnInt8(i8 value) final; + void OnUint8(ui8 value) final; + void OnInt16(i16 value) final; + void OnUint16(ui16 value) final; + void OnInt32(i32 value) final; + void OnUint32(ui32 value) final; + void OnInt64(i64 value) final; + void OnUint64(ui64 value) final; + void OnFloat(float value) final; + void OnDouble(double value) final; + void OnString(TStringBuf value, bool isUtf8) final; + void OnUtf8(TStringBuf value) final; + void OnYson(TStringBuf value, bool isUtf8) final; + void OnJson(TStringBuf value) final; + void OnJsonDocument(TStringBuf value) final; + void OnUuid(TStringBuf value, bool isUtf8) final; + void OnDyNumber(TStringBuf value, bool isUtf8) final; + void OnDate(ui16 value) final; + void OnDatetime(ui32 value) final; + void OnTimestamp(ui64 value) final; + void OnTzDate(TStringBuf value) final; + void OnTzDatetime(TStringBuf value) final; + void OnTzTimestamp(TStringBuf value) final; + void OnInterval(i64 value) final; + void OnDate32(i32 value) final; + void OnDatetime64(i64 value) final; + void OnTimestamp64(i64 value) final; + void OnTzDate32(TStringBuf value) final; + void OnTzDatetime64(TStringBuf value) final; + void OnTzTimestamp64(TStringBuf value) final; + void OnInterval64(i64 value) final; + void OnDecimal(TStringBuf value) final; + void OnBeginOptional() final; + void OnBeforeOptionalItem() final; + void OnAfterOptionalItem() final; + void OnEmptyOptional() final; + void OnEndOptional() final; + void OnBeginList() final; + void OnBeforeListItem() final; + void OnAfterListItem() final; + void OnEndList() final; + void OnBeginTuple() final; + void OnBeforeTupleItem() final; + void OnAfterTupleItem() final; + void OnEndTuple() final; + void OnBeginStruct() final; + void OnBeforeStructItem() final; + void OnAfterStructItem() final; + void OnEndStruct() final; + void OnBeginDict() final; + void OnBeforeDictItem() final; + void OnBeforeDictKey() final; + void OnAfterDictKey() final; + void OnBeforeDictPayload() final; + void OnAfterDictPayload() final; + void OnAfterDictItem() final; + void OnEndDict() final; + void OnBeginVariant(ui32 index) final; + void OnEndVariant() final; + void OnPg(TMaybe value, bool isUtf8) final; + +private: + NYT::TNode& Top(); + void Push(NYT::TNode* value); + void Pop(); + +private: + NYT::TNode Root; + TVector Stack; +}; + +} diff --git a/ydb/library/yql/public/result_format/yql_result_format_impl.h b/ydb/library/yql/public/result_format/yql_result_format_impl.h new file mode 100644 index 000000000000..6a56c350033b --- /dev/null +++ b/ydb/library/yql/public/result_format/yql_result_format_impl.h @@ -0,0 +1,15 @@ +#pragma once +#include "yql_result_format_common.h" + +namespace NYql::NResult { + +inline void Check(bool value, const TSourceLocation& location) { + if (!value) { + throw location + TUnsupportedException(); + } +} + +#define CHECK(value) Check(value, __LOCATION__) +#define UNEXPECTED ythrow TUnsupportedException() << "Unhandled case" + +} diff --git a/ydb/library/yql/public/result_format/yql_result_format_response.cpp b/ydb/library/yql/public/result_format/yql_result_format_response.cpp new file mode 100644 index 000000000000..aad6a150e33a --- /dev/null +++ b/ydb/library/yql/public/result_format/yql_result_format_response.cpp @@ -0,0 +1,111 @@ +#include "yql_result_format_response.h" +#include "yql_result_format_impl.h" + +namespace NYql::NResult { + +TVector ParseResponse(const NYT::TNode& responseNode) { + CHECK(responseNode.IsList()); + TVector v; + for (const auto& resultNode : responseNode.AsList()) { + TResult res; + CHECK(resultNode.IsMap()); + if (resultNode.HasKey("Label")) { + const auto& labelNode = resultNode["Label"]; + CHECK(labelNode.IsString()); + res.Label = labelNode.AsString(); + } + + if (resultNode.HasKey("Position")) { + TPosition pos; + const auto& positionNode = resultNode["Position"]; + CHECK(positionNode.IsMap()); + CHECK(positionNode.HasKey("File")); + const auto& fileNode = positionNode["File"]; + CHECK(fileNode.IsString()); + pos.File = fileNode.AsString(); + CHECK(positionNode.HasKey("Row")); + const auto& rowNode = positionNode["Row"]; + CHECK(rowNode.IsInt64()); + pos.Row = rowNode.AsInt64(); + CHECK(positionNode.HasKey("Column")); + const auto& columnNode = positionNode["Column"]; + CHECK(columnNode.IsInt64()); + pos.Column = columnNode.AsInt64(); + res.Position = pos; + } + + CHECK(resultNode.HasKey("Write")); + const auto& writeNodeList = resultNode["Write"]; + CHECK(writeNodeList.IsList()); + for (const auto& writeNode : writeNodeList.AsList()) { + CHECK(writeNode.IsMap()); + TWrite write; + if (writeNode.HasKey("Type")) { + write.Type = &writeNode["Type"]; + } + + if (writeNode.HasKey("Data")) { + write.Data = &writeNode["Data"]; + } + + if (writeNode.HasKey("Truncated")) { + const auto& truncatedNode = writeNode["Truncated"]; + CHECK(truncatedNode.IsBool()); + write.IsTruncated = truncatedNode.AsBool(); + } + + if (writeNode.HasKey("Refs")) { + const auto& refsNodeList = writeNode["Refs"]; + CHECK(refsNodeList.IsList()); + for (const auto& refNode : refsNodeList.AsList()) { + CHECK(refNode.IsMap()); + CHECK(refNode.HasKey("Reference")); + const auto& referenceNodeList = refNode["Reference"]; + CHECK(referenceNodeList.IsList()); + TFullResultRef ref; + for (const auto& node : referenceNodeList.AsList()) { + CHECK(node.IsString()); + ref.Reference.push_back(node.AsString()); + } + + if (refNode.HasKey("Columns")) { + const auto& columnsNode = refNode["Columns"]; + CHECK(columnsNode.IsList()); + ref.Columns.ConstructInPlace(); + for (const auto& node : columnsNode.AsList()) { + CHECK(node.IsString()); + ref.Columns->push_back(node.AsString()); + } + } + + CHECK(refNode.HasKey("Remove")); + const auto& removeNode = refNode["Remove"]; + CHECK(removeNode.IsBool()); + ref.Remove = removeNode.AsBool(); + + write.Refs.push_back(ref); + } + } + + res.Writes.push_back(write); + } + + if (resultNode.HasKey("Truncated")) { + const auto& truncatedNode = resultNode["Truncated"]; + CHECK(truncatedNode.IsBool()); + res.IsTruncated = truncatedNode.AsBool(); + } + + if (resultNode.HasKey("Unordered")) { + const auto& unorderedNode = resultNode["Unordered"]; + CHECK(unorderedNode.IsBool()); + res.IsUnordered = unorderedNode.AsBool(); + } + + v.push_back(res); + } + + return v; +} + +} diff --git a/ydb/library/yql/public/result_format/yql_result_format_response.h b/ydb/library/yql/public/result_format/yql_result_format_response.h new file mode 100644 index 000000000000..aa22fd71dd5e --- /dev/null +++ b/ydb/library/yql/public/result_format/yql_result_format_response.h @@ -0,0 +1,34 @@ +#pragma once + +#include "yql_result_format_common.h" + +#include + +#include + +namespace NYql::NResult { + +struct TFullResultRef { + TVector Reference; + TMaybe> Columns; + bool Remove = false; +}; + +struct TWrite { + const NYT::TNode* Type = nullptr; + const NYT::TNode* Data = nullptr; + bool IsTruncated = false; + TVector Refs; +}; + +struct TResult { + TMaybe Position; + TMaybe Label; + TVector Writes; + bool IsUnordered = false; + bool IsTruncated = false; +}; + +TVector ParseResponse(const NYT::TNode& responseNode); + +} diff --git a/ydb/library/yql/public/result_format/yql_result_format.cpp b/ydb/library/yql/public/result_format/yql_result_format_type.cpp similarity index 78% rename from ydb/library/yql/public/result_format/yql_result_format.cpp rename to ydb/library/yql/public/result_format/yql_result_format_type.cpp index 740711eb4016..aaccde3d27aa 100644 --- a/ydb/library/yql/public/result_format/yql_result_format.cpp +++ b/ydb/library/yql/public/result_format/yql_result_format_type.cpp @@ -1,22 +1,14 @@ -#include "yql_result_format.h" +#include "yql_result_format_type.h" +#include "yql_result_format_impl.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); @@ -203,7 +195,7 @@ void ParseType(const NYT::TNode& typeNode, ITypeVisitor& visitor) { 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()); + visitor.OnPg(typeNode.AsList()[1].AsString(), typeNode.AsList()[2].AsString()); } else { ythrow TUnsupportedException() << "Unexpected type name: " << name; } @@ -473,7 +465,7 @@ void TTypeBuilder::OnEndTagged() { Pop(); } -void TTypeBuilder::OnPgType(TStringBuf name, TStringBuf category) { +void TTypeBuilder::OnPg(TStringBuf name, TStringBuf category) { Top() = NYT::TNode().Add("PgType").Add(name).Add(category); } @@ -710,7 +702,7 @@ void TSameActionTypeVisitor::OnEndTagged() { Do(); } -void TSameActionTypeVisitor::OnPgType(TStringBuf name, TStringBuf category) { +void TSameActionTypeVisitor::OnPg(TStringBuf name, TStringBuf category) { Y_UNUSED(name); Y_UNUSED(category); Do(); @@ -723,109 +715,4 @@ void TThrowingTypeVisitor::Do() { void TEmptyTypeVisitor::Do() { } -TVector ParseResponse(const NYT::TNode& responseNode) { - CHECK(responseNode.IsList()); - TVector v; - for (const auto& resultNode : responseNode.AsList()) { - TResult res; - CHECK(resultNode.IsMap()); - if (resultNode.HasKey("Label")) { - const auto& labelNode = resultNode["Label"]; - CHECK(labelNode.IsString()); - res.Label = labelNode.AsString(); - } - - if (resultNode.HasKey("Position")) { - TPosition pos; - const auto& positionNode = resultNode["Position"]; - CHECK(positionNode.IsMap()); - CHECK(positionNode.HasKey("File")); - const auto& fileNode = positionNode["File"]; - CHECK(fileNode.IsString()); - pos.File = fileNode.AsString(); - CHECK(positionNode.HasKey("Row")); - const auto& rowNode = positionNode["Row"]; - CHECK(rowNode.IsInt64()); - pos.Row = rowNode.AsInt64(); - CHECK(positionNode.HasKey("Column")); - const auto& columnNode = positionNode["Column"]; - CHECK(columnNode.IsInt64()); - pos.Column = columnNode.AsInt64(); - res.Position = pos; - } - - CHECK(resultNode.HasKey("Write")); - const auto& writeNodeList = resultNode["Write"]; - CHECK(writeNodeList.IsList()); - for (const auto& writeNode : writeNodeList.AsList()) { - CHECK(writeNode.IsMap()); - TWrite write; - if (writeNode.HasKey("Type")) { - write.Type = &writeNode["Type"]; - } - - if (writeNode.HasKey("Data")) { - write.Data = &writeNode["Data"]; - } - - if (writeNode.HasKey("Truncated")) { - const auto& truncatedNode = writeNode["Truncated"]; - CHECK(truncatedNode.IsBool()); - write.IsTruncated = truncatedNode.AsBool(); - } - - if (writeNode.HasKey("Refs")) { - const auto& refsNodeList = writeNode["Refs"]; - CHECK(refsNodeList.IsList()); - for (const auto& refNode : refsNodeList.AsList()) { - CHECK(refNode.IsMap()); - CHECK(refNode.HasKey("Reference")); - const auto& referenceNodeList = refNode["Reference"]; - CHECK(referenceNodeList.IsList()); - TFullResultRef ref; - for (const auto& node : referenceNodeList.AsList()) { - CHECK(node.IsString()); - ref.Reference.push_back(node.AsString()); - } - - if (refNode.HasKey("Columns")) { - const auto& columnsNode = refNode["Columns"]; - CHECK(columnsNode.IsList()); - ref.Columns.ConstructInPlace(); - for (const auto& node : columnsNode.AsList()) { - CHECK(node.IsString()); - ref.Columns->push_back(node.AsString()); - } - } - - CHECK(refNode.HasKey("Remove")); - const auto& removeNode = refNode["Remove"]; - CHECK(removeNode.IsBool()); - ref.Remove = removeNode.AsBool(); - - write.Refs.push_back(ref); - } - } - - res.Writes.push_back(write); - } - - if (resultNode.HasKey("Truncated")) { - const auto& truncatedNode = resultNode["Truncated"]; - CHECK(truncatedNode.IsBool()); - res.IsTruncated = truncatedNode.AsBool(); - } - - if (resultNode.HasKey("Unordered")) { - const auto& unorderedNode = resultNode["Unordered"]; - CHECK(unorderedNode.IsBool()); - res.IsUnordered = unorderedNode.AsBool(); - } - - v.push_back(res); - } - - return v; -} - } diff --git a/ydb/library/yql/public/result_format/yql_result_format.h b/ydb/library/yql/public/result_format/yql_result_format_type.h similarity index 87% rename from ydb/library/yql/public/result_format/yql_result_format.h rename to ydb/library/yql/public/result_format/yql_result_format_type.h index 7da341e4dac2..0eb0b1731581 100644 --- a/ydb/library/yql/public/result_format/yql_result_format.h +++ b/ydb/library/yql/public/result_format/yql_result_format_type.h @@ -1,37 +1,11 @@ #pragma once -#include +#include "yql_result_format_common.h" -#include #include namespace NYql::NResult { -class TUnsupportedException : public yexception {}; - -struct TFullResultRef { - TVector Reference; - TMaybe> Columns; - bool Remove = false; -}; - -struct TWrite { - const NYT::TNode* Type = nullptr; - const NYT::TNode* Data = nullptr; - bool IsTruncated = false; - TVector Refs; -}; - -struct TResult { - TMaybe Position; - TMaybe Label; - TVector Writes; - bool IsUnordered = false; - bool IsTruncated = false; -}; - -TVector ParseResponse(const NYT::TNode& responseNode); - class ITypeVisitor { public: virtual ~ITypeVisitor() = default; @@ -91,7 +65,7 @@ class ITypeVisitor { virtual void OnEndVariant() = 0; virtual void OnBeginTagged(TStringBuf tag) = 0; virtual void OnEndTagged() = 0; - virtual void OnPgType(TStringBuf name, TStringBuf category) = 0; + virtual void OnPg(TStringBuf name, TStringBuf category) = 0; }; class TSameActionTypeVisitor : public ITypeVisitor { @@ -151,7 +125,7 @@ class TSameActionTypeVisitor : public ITypeVisitor { void OnEndVariant() override; void OnBeginTagged(TStringBuf tag) override; void OnEndTagged() override; - void OnPgType(TStringBuf name, TStringBuf category) override; + void OnPg(TStringBuf name, TStringBuf category) override; public: virtual void Do() = 0; @@ -229,7 +203,7 @@ class TTypeBuilder : public ITypeVisitor { void OnEndVariant() final; void OnBeginTagged(TStringBuf tag) final; void OnEndTagged() final; - void OnPgType(TStringBuf name, TStringBuf category) final; + void OnPg(TStringBuf name, TStringBuf category) final; private: NYT::TNode& Top(); diff --git a/ydb/library/yql/sql/pg_dummy/pg_sql_dummy.cpp b/ydb/library/yql/sql/pg_dummy/pg_sql_dummy.cpp index 6707d06c1a5a..98d20b018a05 100644 --- a/ydb/library/yql/sql/pg_dummy/pg_sql_dummy.cpp +++ b/ydb/library/yql/sql/pg_dummy/pg_sql_dummy.cpp @@ -82,7 +82,7 @@ TString PgValueCoerce(const NUdf::TUnboxedValuePod& value, ui32 pgTypeId, i32 ty throw yexception() << "PgValueCoerce: PG types are not supported"; } -void WriteYsonValuePg(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TPgType* type, +void WriteYsonValuePg(NResult::TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TPgType* type, const TVector* structPositions) { Y_UNUSED(writer); Y_UNUSED(value); diff --git a/ydb/library/yql/tools/dqrun/dqrun.cpp b/ydb/library/yql/tools/dqrun/dqrun.cpp index e6b9f01b1d90..32de31a60942 100644 --- a/ydb/library/yql/tools/dqrun/dqrun.cpp +++ b/ydb/library/yql/tools/dqrun/dqrun.cpp @@ -75,7 +75,9 @@ #include #include #include -#include +#include +#include +#include #include #include @@ -444,6 +446,11 @@ int RunProgram(TProgramPtr program, const TRunOptions& options, const THashMap #include #include -#include +#include +#include +#include #include @@ -896,6 +898,11 @@ int Main(int argc, const char *argv[]) NResult::TEmptyTypeVisitor visitor; NResult::ParseType(*write.Type, visitor); } + + if (write.Type && write.Data) { + NResult::TEmptyDataVisitor visitor; + NResult::ParseData(*write.Type, *write.Data, visitor); + } } } }