diff options
author | vvvv <vvvv@yandex-team.ru> | 2022-02-25 04:31:17 +0300 |
---|---|---|
committer | vvvv <vvvv@yandex-team.ru> | 2022-02-25 04:31:17 +0300 |
commit | 66834feb30614a28410b37b4be1842f6eb9fc7ed (patch) | |
tree | 382c6fbe2ecc9271900888e86076ad0e5d2776bf | |
parent | 0d27a6699fbcf898a0c322d3eb845fffd711a0f1 (diff) | |
download | ydb-66834feb30614a28410b37b4be1842f6eb9fc7ed.tar.gz |
YQL-13710 initial runtime support for PgConst, introduced PgType in Expr/Mkql types
ref:e65ae23014cb20961183f1f49314023cdc9259a2
45 files changed, 368 insertions, 10 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 71f86a831f..7695ea3b6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -332,6 +332,7 @@ add_subdirectory(library/cpp/cppparser) add_subdirectory(ydb/library/yql/public/issue/protos) add_subdirectory(ydb/library/yql/core/issue/protos) add_subdirectory(tools/rescompiler/bin) +add_subdirectory(ydb/library/yql/parser/pg_catalog) add_subdirectory(ydb/library/yql/sql/settings) add_subdirectory(library/cpp/deprecated/split) add_subdirectory(library/cpp/deprecated/kmp) @@ -1172,7 +1173,6 @@ add_subdirectory(ydb/core/kesus/tablet/quoter_performance_test) add_subdirectory(ydb/core/ymq/client/bin) add_subdirectory(ydb/core/ymq/client/cpp) add_subdirectory(ydb/core/yq/libs/pretty_printers) -add_subdirectory(ydb/library/yql/parser/pg_catalog) add_subdirectory(ydb/library/yql/parser/lexer_common) add_subdirectory(ydb/library/yql/utils/threading) add_subdirectory(ydb/public/sdk/cpp/client/ydb_persqueue_core/ut/with_offset_ranges_mode_ut) diff --git a/ydb/core/yq/libs/pretty_printers/minikql_program_printer.cpp b/ydb/core/yq/libs/pretty_printers/minikql_program_printer.cpp index 8c80588457..497c39f320 100644 --- a/ydb/core/yq/libs/pretty_printers/minikql_program_printer.cpp +++ b/ydb/core/yq/libs/pretty_printers/minikql_program_printer.cpp @@ -32,6 +32,9 @@ public: void Visit(TDataType&) override { Out << "DataType"; } + void Visit(TPgType&) override { + Out << "PgType"; + } void Visit(TStructType&) override { Out << "StructType"; } diff --git a/ydb/library/yql/ast/CMakeLists.txt b/ydb/library/yql/ast/CMakeLists.txt index 6c3666d48b..78585f3515 100644 --- a/ydb/library/yql/ast/CMakeLists.txt +++ b/ydb/library/yql/ast/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(library-yql-ast PUBLIC yql-public-udf library-yql-utils yql-core-issue + yql-parser-pg_catalog ) target_sources(library-yql-ast PRIVATE ${CMAKE_SOURCE_DIR}/ydb/library/yql/ast/yql_ast.cpp diff --git a/ydb/library/yql/ast/ya.make b/ydb/library/yql/ast/ya.make index 2d55860c89..38ec05deba 100644 --- a/ydb/library/yql/ast/ya.make +++ b/ydb/library/yql/ast/ya.make @@ -41,6 +41,7 @@ PEERDIR( ydb/library/yql/public/udf ydb/library/yql/utils ydb/library/yql/core/issue + ydb/library/yql/parser/pg_catalog ) END() diff --git a/ydb/library/yql/ast/yql_expr.cpp b/ydb/library/yql/ast/yql_expr.cpp index 82f6c5812a..e91a95adff 100644 --- a/ydb/library/yql/ast/yql_expr.cpp +++ b/ydb/library/yql/ast/yql_expr.cpp @@ -4,6 +4,7 @@ #include <ydb/library/yql/utils/utf8.h> +#include <ydb/library/yql/parser/pg_catalog/catalog.h> #include <library/cpp/containers/stack_vector/stack_vec.h> #include <util/generic/hash.h> #include <util/generic/size_literals.h> @@ -230,6 +231,15 @@ namespace { return ann; } + } else if (content == TStringBuf("Pg")) { + const auto count = node.GetChildrenCount(); + if (count != 2 || !node.GetChild(1)->IsAtom()) { + AddError(node, "Bad data type annotation"); + return nullptr; + } + + auto typeId = NPg::LookupType(TString(node.GetChild(1)->GetContent())).TypeId; + return Expr.MakeType<TPgExprType>(typeId); } else if (content == TStringBuf("List")) { if (node.GetChildrenCount() != 2) { AddError(node, "Bad list type annotation"); @@ -627,6 +637,13 @@ namespace { return TAstNode::NewList(TPosition(), pool, self, datatype); } + case ETypeAnnotationKind::Pg: + { + auto self = TAstNode::NewLiteralAtom(TPosition(), TStringBuf("Pg"), pool); + auto name = TAstNode::NewLiteralAtom(TPosition(), annotation.Cast<TPgExprType>()->GetName(), pool); + return TAstNode::NewList(TPosition(), pool, self, name); + } + case ETypeAnnotationKind::World: { return TAstNode::NewLiteralAtom(TPosition(), TStringBuf("World"), pool); @@ -2861,6 +2878,10 @@ bool TTaggedExprType::Validate(TPositionHandle position, TExprContext& ctx) cons return Validate(ctx.GetPosition(position), ctx); } +const TString& TPgExprType::GetName() const { + return NPg::LookupType(TypeId).Name; +} + TExprContext::TExprContext(ui64 nextUniqueId) : StringPool(4096) , NextUniqueId(nextUniqueId) @@ -3054,6 +3075,15 @@ const TDataExprType* TMakeTypeImpl<TDataExprType>::Make(TExprContext& ctx, EData return AddType<TDataExprType>(ctx, hash, slot); } +const TPgExprType* TMakeTypeImpl<TPgExprType>::Make(TExprContext& ctx, ui32 typeId) { + const auto hash = TPgExprType::MakeHash(typeId); + TPgExprType sample(hash, typeId); + if (const auto found = FindType(sample, ctx)) + return found; + + return AddType<TPgExprType>(ctx, hash, typeId); +} + const TDataExprParamsType* TMakeTypeImpl<TDataExprParamsType>::Make(TExprContext& ctx, EDataSlot slot, const TStringBuf& one, const TStringBuf& two) { const auto hash = TDataExprParamsType::MakeHash(slot, one, two); TDataExprParamsType sample(hash, slot, one, two); diff --git a/ydb/library/yql/ast/yql_expr.h b/ydb/library/yql/ast/yql_expr.h index d6eb544f9a..f8638afbd7 100644 --- a/ydb/library/yql/ast/yql_expr.h +++ b/ydb/library/yql/ast/yql_expr.h @@ -59,6 +59,7 @@ class TItemExprType; class TListExprType; class TStreamExprType; class TDataExprType; +class TPgExprType; class TWorldExprType; class TOptionalExprType; class TCallableExprType; @@ -92,6 +93,7 @@ struct TTypeAnnotationVisitor { virtual void Visit(const TStreamExprType& type) = 0; virtual void Visit(const TFlowExprType& type) = 0; virtual void Visit(const TDataExprType& type) = 0; + virtual void Visit(const TPgExprType& type) = 0; virtual void Visit(const TWorldExprType& type) = 0; virtual void Visit(const TOptionalExprType& type) = 0; virtual void Visit(const TCallableExprType& type) = 0; @@ -695,6 +697,35 @@ private: const TStringBuf One, Two; }; +class TPgExprType : public TTypeAnnotationNode { +public: + static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Pg; + + TPgExprType(ui64 hash, ui32 typeId) + : TTypeAnnotationNode(KindValue, TypeHasManyValues, hash) + , TypeId(typeId) + { + } + + static ui64 MakeHash(ui32 typeId) { + ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Pg; + return StreamHash(typeId, hash); + } + + const TString& GetName() const; + + ui32 GetId() const { + return TypeId; + } + + bool operator==(const TPgExprType& other) const { + return TypeId == other.TypeId; + } + +private: + ui32 TypeId; +}; + class TWorldExprType : public TTypeAnnotationNode { public: static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::World; @@ -1191,6 +1222,9 @@ inline bool TTypeAnnotationNode::Equals(const TTypeAnnotationNode& node) const { case ETypeAnnotationKind::Data: return static_cast<const TDataExprType&>(*this) == static_cast<const TDataExprType&>(node); + case ETypeAnnotationKind::Pg: + return static_cast<const TPgExprType&>(*this) == static_cast<const TPgExprType&>(node); + case ETypeAnnotationKind::World: return static_cast<const TWorldExprType&>(*this) == static_cast<const TWorldExprType&>(node); @@ -1263,6 +1297,8 @@ inline void TTypeAnnotationNode::Accept(TTypeAnnotationVisitor& visitor) const { return visitor.Visit(static_cast<const TListExprType&>(*this)); case ETypeAnnotationKind::Data: return visitor.Visit(static_cast<const TDataExprType&>(*this)); + case ETypeAnnotationKind::Pg: + return visitor.Visit(static_cast<const TPgExprType&>(*this)); case ETypeAnnotationKind::World: return visitor.Visit(static_cast<const TWorldExprType&>(*this)); case ETypeAnnotationKind::Optional: @@ -2154,6 +2190,11 @@ struct TMakeTypeImpl<TDataExprType> { }; template <> +struct TMakeTypeImpl<TPgExprType> { + static const TPgExprType* Make(TExprContext& ctx, ui32 typeId); +}; + +template <> struct TMakeTypeImpl<TDataExprParamsType> { static const TDataExprParamsType* Make(TExprContext& ctx, EDataSlot slot, const TStringBuf& one, const TStringBuf& two); }; diff --git a/ydb/library/yql/ast/yql_expr_types.h b/ydb/library/yql/ast/yql_expr_types.h index 391fa1ca97..c420b45e49 100644 --- a/ydb/library/yql/ast/yql_expr_types.h +++ b/ydb/library/yql/ast/yql_expr_types.h @@ -27,7 +27,8 @@ namespace NYql { xx(Flow, 20) \ xx(EmptyList, 21) \ xx(EmptyDict, 22) \ - xx(Multi, 23) + xx(Multi, 23) \ + xx(Pg, 24) enum class ETypeAnnotationKind : ui64 { YQL_TYPE_ANN_KIND_MAP(ENUM_VALUE_GEN) diff --git a/ydb/library/yql/ast/yql_type_string.cpp b/ydb/library/yql/ast/yql_type_string.cpp index af9af93259..149a062bb1 100644 --- a/ydb/library/yql/ast/yql_type_string.cpp +++ b/ydb/library/yql/ast/yql_type_string.cpp @@ -1178,6 +1178,10 @@ private: } } + void Visit(const TPgExprType& type) final { + Out_ << "pg_" << type.GetName(); + } + void Visit(const TWorldExprType& type) final { Y_UNUSED(type); Out_ << TStringBuf("World"); diff --git a/ydb/library/yql/core/type_ann/CMakeLists.txt b/ydb/library/yql/core/type_ann/CMakeLists.txt index 1aa0288d18..f5394370b6 100644 --- a/ydb/library/yql/core/type_ann/CMakeLists.txt +++ b/ydb/library/yql/core/type_ann/CMakeLists.txt @@ -14,6 +14,7 @@ target_link_libraries(yql-core-type_ann PUBLIC yql-core-issue core-issue-protos common-schema-expr + yql-parser-pg_catalog ) target_sources(yql-core-type_ann PRIVATE ${CMAKE_SOURCE_DIR}/ydb/library/yql/core/type_ann/type_ann_core.cpp diff --git a/ydb/library/yql/core/type_ann/type_ann_core.cpp b/ydb/library/yql/core/type_ann/type_ann_core.cpp index 9596c5942b..c2eb154c99 100644 --- a/ydb/library/yql/core/type_ann/type_ann_core.cpp +++ b/ydb/library/yql/core/type_ann/type_ann_core.cpp @@ -21,6 +21,7 @@ #include <ydb/library/yql/public/udf/udf_data_type.h> #include <ydb/library/yql/providers/common/schema/expr/yql_expr_schema.h> #include <ydb/library/yql/utils/utf8.h> +#include <ydb/library/yql/parser/pg_catalog/catalog.h> #include <ydb/library/yql/minikql/mkql_program_builder.h> #include <ydb/library/yql/minikql/mkql_type_ops.h> @@ -9359,6 +9360,25 @@ template <NKikimr::NUdf::EDataSlot DataSlot> return IGraphTransformer::TStatus::Ok; } + IGraphTransformer::TStatus PgConstWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) { + Y_UNUSED(output); + if (!EnsureArgsCount(*input, 2, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (!EnsureAtom(*input->Child(0), ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + if (!EnsureAtom(*input->Child(1), ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + auto typeId = NPg::LookupType(TString(input->Child(0)->Content())).TypeId; + input->SetTypeAnn(ctx.Expr.MakeType<TPgExprType>(typeId)); + return IGraphTransformer::TStatus::Ok; + } + using TInputs = TVector<std::tuple<TString, const TStructExprType*, TMaybe<TColumnOrder>>>; bool ScanColumns(TExprNode::TPtr root, const TInputs& inputs, const THashSet<TString>& possibleAliases, @@ -13072,6 +13092,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot> Functions["PgGroup"] = &PgWhereWrapper; Functions["PgWindow"] = &PgWindowWrapper; Functions["PgAnonWindow"] = &PgAnonWindowWrapper; + Functions["PgConst"] = &PgConstWrapper; Functions["AutoDemuxList"] = &AutoDemuxListWrapper; Functions["AggrCountInit"] = &AggrCountInitWrapper; Functions["AggrCountUpdate"] = &AggrCountUpdateWrapper; diff --git a/ydb/library/yql/core/type_ann/ya.make b/ydb/library/yql/core/type_ann/ya.make index be843b5abc..03e0e3a657 100644 --- a/ydb/library/yql/core/type_ann/ya.make +++ b/ydb/library/yql/core/type_ann/ya.make @@ -32,6 +32,7 @@ PEERDIR( ydb/library/yql/core/issue ydb/library/yql/core/issue/protos ydb/library/yql/providers/common/schema/expr + ydb/library/yql/parser/pg_catalog ) YQL_LAST_ABI_VERSION() diff --git a/ydb/library/yql/core/yql_type_annotation.h b/ydb/library/yql/core/yql_type_annotation.h index 1a1f1fb476..3f960f0613 100644 --- a/ydb/library/yql/core/yql_type_annotation.h +++ b/ydb/library/yql/core/yql_type_annotation.h @@ -226,6 +226,8 @@ struct TTypeAnnotationContext: public TThrRefBase { bool OrderedColumns = false; TColumnOrderStorage::TPtr ColumnOrderStorage = new TColumnOrderStorage; + bool PgTypes = false; + TMaybe<TColumnOrder> LookupColumnOrder(const TExprNode& node) const; IGraphTransformer::TStatus SetColumnOrder(const TExprNode& node, const TColumnOrder& columnOrder, TExprContext& ctx); diff --git a/ydb/library/yql/dq/runtime/dq_arrow_helpers.cpp b/ydb/library/yql/dq/runtime/dq_arrow_helpers.cpp index 6d63c9873e..94b656e4bb 100644 --- a/ydb/library/yql/dq/runtime/dq_arrow_helpers.cpp +++ b/ydb/library/yql/dq/runtime/dq_arrow_helpers.cpp @@ -508,6 +508,7 @@ bool IsArrowCompatible(const NKikimr::NMiniKQL::TType* type) { case TType::EKind::ReservedKind: case TType::EKind::Flow: case TType::EKind::Tagged: + case TType::EKind::Pg: return false; } return false; diff --git a/ydb/library/yql/dq/runtime/dq_transport.cpp b/ydb/library/yql/dq/runtime/dq_transport.cpp index 93b85b0c6f..7008b1a369 100644 --- a/ydb/library/yql/dq/runtime/dq_transport.cpp +++ b/ydb/library/yql/dq/runtime/dq_transport.cpp @@ -389,6 +389,7 @@ ui64 EstimateSizeImpl(const NUdf::TUnboxedValuePod& value, const NKikimr::NMiniK case TType::EKind::ReservedKind: case TType::EKind::Tagged: case TType::EKind::Block: + case TType::EKind::Pg: THROW yexception() << "Unsupported type: " << type->GetKindAsStr(); } } diff --git a/ydb/library/yql/minikql/CMakeLists.txt b/ydb/library/yql/minikql/CMakeLists.txt index 58e379e4c8..cef7c0425e 100644 --- a/ydb/library/yql/minikql/CMakeLists.txt +++ b/ydb/library/yql/minikql/CMakeLists.txt @@ -20,6 +20,7 @@ target_link_libraries(library-yql-minikql PUBLIC yql-public-udf public-udf-tz library-yql-utils + yql-parser-pg_catalog ) target_sources(library-yql-minikql PRIVATE ${CMAKE_SOURCE_DIR}/ydb/library/yql/minikql/aligned_page_pool.cpp diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp index f2b188ae47..319f26093c 100644 --- a/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp +++ b/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp @@ -270,6 +270,10 @@ private: VisitType<TDataType>(node); } + void Visit(TPgType& node) override { + VisitType<TPgType>(node); + } + void Visit(TStructType& node) override { VisitType<TStructType>(node); } diff --git a/ydb/library/yql/minikql/mkql_node.cpp b/ydb/library/yql/minikql/mkql_node.cpp index 4c6f3e45ad..f1d854645a 100644 --- a/ydb/library/yql/minikql/mkql_node.cpp +++ b/ydb/library/yql/minikql/mkql_node.cpp @@ -3,6 +3,7 @@ #include "mkql_node_cast.h" #include "mkql_node_visitor.h" #include "mkql_node_printer.h" +#include <ydb/library/yql/parser/pg_catalog/catalog.h> #include <util/stream/str.h> #include <util/string/join.h> @@ -210,6 +211,7 @@ TStringBuf TType::GetKindAsStr() const { xx(EmptyDict, TEmptyDictType) \ xx(Tagged, TTaggedType) \ xx(Block, TBlockType) \ + xx(Pg, TPgType) \ void TType::Accept(INodeVisitor& visitor) { switch (Kind) { @@ -462,6 +464,42 @@ bool TDataLiteral::Equals(const TDataLiteral& nodeToCompare) const { } } +TPgType::TPgType(ui32 typeId, const TTypeEnvironment& env) + : TType(EKind::Pg, env.GetTypeOfType()) + , TypeId(typeId) +{ +} + +TPgType* TPgType::Create(ui32 typeId, const TTypeEnvironment& env) { + return ::new(env.Allocate<TPgType>()) TPgType(typeId, env); +} + +bool TPgType::IsSameType(const TPgType& typeToCompare) const { + return TypeId == typeToCompare.TypeId; +} + +bool TPgType::IsConvertableTo(const TPgType& typeToCompare, bool ignoreTagged) const { + Y_UNUSED(ignoreTagged); + return IsSameType(typeToCompare); +} + +void TPgType::DoUpdateLinks(const THashMap<TNode*, TNode*>& links) { + Y_UNUSED(links); +} + +TNode* TPgType::DoCloneOnCallableWrite(const TTypeEnvironment& env) const { + Y_UNUSED(env); + return const_cast<TPgType*>(this); +} + +void TPgType::DoFreeze(const TTypeEnvironment& env) { + Y_UNUSED(env); +} + +const TString& TPgType::GetName() const { + return NYql::NPg::LookupType(TypeId).Name; +} + TStructType::TStructType(ui32 membersCount, std::pair<TInternName, TType*>* members, const TTypeEnvironment& env, bool validate) : TType(EKind::Struct, env.GetTypeOfType()) diff --git a/ydb/library/yql/minikql/mkql_node.h b/ydb/library/yql/minikql/mkql_node.h index ee74455ea6..e44307f942 100644 --- a/ydb/library/yql/minikql/mkql_node.h +++ b/ydb/library/yql/minikql/mkql_node.h @@ -148,7 +148,8 @@ class TTypeEnvironment; XX(EmptyList, 16 + 2) \ XX(EmptyDict, 32 + 2) \ XX(Tagged, 48 + 7) \ - XX(Block, 16 + 13) + XX(Block, 16 + 13) \ + XX(Pg, 16 + 3) class TType : public TNode { public: @@ -279,6 +280,7 @@ class TAnyType; class TTupleLiteral; class TResourceType; class TDataType; +class TPgType; // A non-owning reference to internalized string @@ -584,6 +586,34 @@ private: void DoFreeze(const TTypeEnvironment& env); }; +class TPgType : public TType { + friend class TType; +public: + static TPgType* Create(ui32 typeId, const TTypeEnvironment& env); + + using TType::IsSameType; + bool IsSameType(const TPgType& typeToCompare) const; + + using TType::IsConvertableTo; + bool IsConvertableTo(const TPgType& typeToCompare, bool ignoreTagged = false) const; + + ui32 GetTypeId() const { + return TypeId; + } + + const TString& GetName() const; + +protected: + TPgType(ui32 typeId, const TTypeEnvironment& env); + + void DoUpdateLinks(const THashMap<TNode*, TNode*>& links); + TNode* DoCloneOnCallableWrite(const TTypeEnvironment& env) const; + void DoFreeze(const TTypeEnvironment& env); + +private: + const ui32 TypeId; +}; + struct TStructMember { TStructMember() : Type(nullptr) diff --git a/ydb/library/yql/minikql/mkql_node_cast.cpp b/ydb/library/yql/minikql/mkql_node_cast.cpp index 0a62a7d615..84344f2cb4 100644 --- a/ydb/library/yql/minikql/mkql_node_cast.cpp +++ b/ydb/library/yql/minikql/mkql_node_cast.cpp @@ -53,6 +53,7 @@ MKQL_AS_TYPE(Stream) MKQL_AS_TYPE(Flow) MKQL_AS_TYPE(Tagged) MKQL_AS_TYPE(Block) +MKQL_AS_TYPE(Pg) MKQL_AS_VALUE(Any, Type) MKQL_AS_VALUE(Callable, Type) diff --git a/ydb/library/yql/minikql/mkql_node_printer.cpp b/ydb/library/yql/minikql/mkql_node_printer.cpp index f7515a3005..831b657a4d 100644 --- a/ydb/library/yql/minikql/mkql_node_printer.cpp +++ b/ydb/library/yql/minikql/mkql_node_printer.cpp @@ -2,6 +2,7 @@ #include "mkql_node_visitor.h" #include <util/stream/str.h> #include <ydb/library/yql/public/udf/udf_types.h> +#include <ydb/library/yql/parser/pg_catalog/catalog.h> namespace NKikimr { namespace NMiniKQL { @@ -83,6 +84,12 @@ namespace { WriteNewline(); } + void Visit(TPgType& node) override { + WriteIndentation(); + Out << "Type (Pg), name: " << NYql::NPg::LookupType(node.GetTypeId()).Name; + WriteNewline(); + } + void Visit(TStructType& node) override { WriteIndentation(); Out << "Type (Struct) with " << node.GetMembersCount() << " members {"; diff --git a/ydb/library/yql/minikql/mkql_node_printer_ut.cpp b/ydb/library/yql/minikql/mkql_node_printer_ut.cpp index ec8c5d1afe..9a50e7a040 100644 --- a/ydb/library/yql/minikql/mkql_node_printer_ut.cpp +++ b/ydb/library/yql/minikql/mkql_node_printer_ut.cpp @@ -78,6 +78,7 @@ namespace { structBuilder.Add("43", TRuntimeNode(TTaggedType::Create(dtype1, "mytag", env), true)); structBuilder.Add("44", TRuntimeNode(TBlockType::Create(dtype1, TBlockType::EShape::Single, env), true)); structBuilder.Add("45", TRuntimeNode(TBlockType::Create(dtype2, TBlockType::EShape::Many, env), true)); + structBuilder.Add("46", TRuntimeNode(TPgType::Create(23, env), true)); // int4 type return structBuilder.Build(); } } diff --git a/ydb/library/yql/minikql/mkql_node_serialization.cpp b/ydb/library/yql/minikql/mkql_node_serialization.cpp index e314f38cd6..4ebe5ba9f3 100644 --- a/ydb/library/yql/minikql/mkql_node_serialization.cpp +++ b/ydb/library/yql/minikql/mkql_node_serialization.cpp @@ -154,6 +154,18 @@ namespace { IsProcessed0 = false; } + void Visit(TPgType& node) override { + if (node.GetCookie() != 0) { + Owner.WriteReference(node); + IsProcessed0 = true; + return; + } + + Owner.Write(TypeMarker | (char)TType::EKind::Pg); + Owner.WriteVar32(node.GetTypeId()); + IsProcessed0 = false; + } + void Visit(TStructType& node) override { if (node.GetCookie() != 0) { Owner.WriteReference(node); @@ -575,6 +587,10 @@ namespace { Owner.RegisterReference(node); } + void Visit(TPgType& node) override { + Owner.RegisterReference(node); + } + void Visit(TStructType& node) override { for (ui32 i = 0, e = node.GetMembersCount(); i < e; ++i) { auto memberName = node.GetMemberNameStr(i); @@ -1174,7 +1190,7 @@ namespace { case TType::EKind::Void: return ReadVoidOrEmptyListOrEmptyDictType(code); case TType::EKind::Data: - return ReadDataType(); + return ReadDataOrPgType(code); case TType::EKind::Struct: return ReadStructType(); case TType::EKind::List: @@ -1236,6 +1252,12 @@ namespace { return Nodes.back(); } + TNode* ReadPgType() { + const auto typeId = ReadVar32(); + Nodes.emplace_back(TPgType::Create(typeId, Env)); + return Nodes.back(); + } + ui32 TryReadKeyType(char code) { const bool isRoot = (code & UserMarker1) != 0; const bool hasStaticValue = (code & UserMarker2) != 0; @@ -1385,6 +1407,15 @@ namespace { } } + TNode* ReadDataOrPgType(char code) { + switch ((TType::EKind)(code & TypeMask)) { + case TType::EKind::Data: return ReadDataType(); + case TType::EKind::Pg: return ReadPgType(); + default: + ThrowCorrupted(); + } + } + TNode* ReadDictType() { auto keyTypeNode = PopNode(); if (keyTypeNode->GetType()->GetKind() != TType::EKind::Type) diff --git a/ydb/library/yql/minikql/mkql_node_visitor.cpp b/ydb/library/yql/minikql/mkql_node_visitor.cpp index 5a4ac8e479..cc8a8562f4 100644 --- a/ydb/library/yql/minikql/mkql_node_visitor.cpp +++ b/ydb/library/yql/minikql/mkql_node_visitor.cpp @@ -41,6 +41,11 @@ void TThrowingNodeVisitor::Visit(TDataType& node) { ThrowUnexpectedNodeType(); } +void TThrowingNodeVisitor::Visit(TPgType& node) { + Y_UNUSED(node); + ThrowUnexpectedNodeType(); +} + void TThrowingNodeVisitor::Visit(TStructType& node) { Y_UNUSED(node); ThrowUnexpectedNodeType(); @@ -199,6 +204,10 @@ void TEmptyNodeVisitor::Visit(TDataType& node) { Y_UNUSED(node); } +void TEmptyNodeVisitor::Visit(TPgType& node) { + Y_UNUSED(node); +} + void TEmptyNodeVisitor::Visit(TStructType& node) { Y_UNUSED(node); } @@ -327,6 +336,10 @@ void TExploringNodeVisitor::Visit(TDataType& node) { AddChildNode(&node, *node.GetType()); } +void TExploringNodeVisitor::Visit(TPgType& node) { + AddChildNode(&node, *node.GetType()); +} + void TExploringNodeVisitor::Visit(TStructType& node) { AddChildNode(&node, *node.GetType()); for (ui32 i = 0, e = node.GetMembersCount(); i < e; ++i) { diff --git a/ydb/library/yql/minikql/mkql_node_visitor.h b/ydb/library/yql/minikql/mkql_node_visitor.h index f5bf76d520..5c4528b517 100644 --- a/ydb/library/yql/minikql/mkql_node_visitor.h +++ b/ydb/library/yql/minikql/mkql_node_visitor.h @@ -20,6 +20,7 @@ public: virtual void Visit(TEmptyListType& node) = 0; virtual void Visit(TEmptyDictType& node) = 0; virtual void Visit(TDataType& node) = 0; + virtual void Visit(TPgType& node) = 0; virtual void Visit(TStructType& node) = 0; virtual void Visit(TListType& node) = 0; virtual void Visit(TOptionalType& node) = 0; @@ -56,6 +57,7 @@ public: void Visit(TEmptyListType& node) override; void Visit(TEmptyDictType& node) override; void Visit(TDataType& node) override; + void Visit(TPgType& node) override; void Visit(TStructType& node) override; void Visit(TListType& node) override; void Visit(TOptionalType& node) override; @@ -95,6 +97,7 @@ public: void Visit(TEmptyListType& node) override; void Visit(TEmptyDictType& node) override; void Visit(TDataType& node) override; + void Visit(TPgType& node) override; void Visit(TStructType& node) override; void Visit(TListType& node) override; void Visit(TOptionalType& node) override; @@ -133,6 +136,7 @@ public: void Visit(TEmptyListType& node) override; void Visit(TEmptyDictType& node) override; void Visit(TDataType& node) override; + void Visit(TPgType& node) override; void Visit(TStructType& node) override; void Visit(TListType& node) override; void Visit(TOptionalType& node) override; diff --git a/ydb/library/yql/minikql/mkql_program_builder.cpp b/ydb/library/yql/minikql/mkql_program_builder.cpp index f2c09fac88..ffbdf61c2f 100644 --- a/ydb/library/yql/minikql/mkql_program_builder.cpp +++ b/ydb/library/yql/minikql/mkql_program_builder.cpp @@ -2040,6 +2040,10 @@ TType* TProgramBuilder::NewDataType(NUdf::TDataTypeId schemeType, bool optional) return optional ? NewOptionalType(TDataType::Create(schemeType, Env)) : TDataType::Create(schemeType, Env); } +TType* TProgramBuilder::NewPgType(ui32 typeId) { + return TPgType::Create(typeId, Env); +} + TType* TProgramBuilder::NewDecimalType(ui8 precision, ui8 scale) { return TDataDecimalType::Create(precision, scale, Env); } @@ -5011,6 +5015,17 @@ TRuntimeNode TProgramBuilder::Replicate(TRuntimeNode item, TRuntimeNode count, c return TRuntimeNode(callableBuilder.Build(), false); } +TRuntimeNode TProgramBuilder::PgConst(TPgType* pgType, const std::string_view& value) { + if constexpr (RuntimeVersion < 30U) { + THROW yexception() << "Runtime version (" << RuntimeVersion << ") too old for " << __func__; + } + + TCallableBuilder callableBuilder(Env, __func__, pgType); + callableBuilder.Add(NewDataLiteral(pgType->GetTypeId())); + callableBuilder.Add(NewDataLiteral<NUdf::EDataSlot::String>(value)); + return TRuntimeNode(callableBuilder.Build(), false); +} + bool CanExportType(TType* type, const TTypeEnvironment& env) { if (type->GetKind() == TType::EKind::Type) { return false; // Type of Type diff --git a/ydb/library/yql/minikql/mkql_program_builder.h b/ydb/library/yql/minikql/mkql_program_builder.h index 0d8402d46c..1e6f521a68 100644 --- a/ydb/library/yql/minikql/mkql_program_builder.h +++ b/ydb/library/yql/minikql/mkql_program_builder.h @@ -135,6 +135,7 @@ public: } TType* NewDecimalType(ui8 precision, ui8 scale); + TType* NewPgType(ui32 typeId); template <typename T, typename = std::enable_if_t<NUdf::TKnownDataType<T>::Result>> TRuntimeNode NewDataLiteral(T data) const { @@ -622,6 +623,8 @@ public: typedef TRuntimeNode (TProgramBuilder::*ProcessFunctionMethod)(TRuntimeNode, const TUnaryLambda&); typedef TRuntimeNode (TProgramBuilder::*NarrowFunctionMethod)(TRuntimeNode, const TNarrowLambda&); + TRuntimeNode PgConst(TPgType* pgType, const std::string_view& value); + protected: TRuntimeNode Invoke(const std::string_view& funcName, TType* resultType, const TArrayRef<const TRuntimeNode>& args); TRuntimeNode IfPresent(TRuntimeNode optional, const TUnaryLambda& thenBranch, TRuntimeNode elseBranch); diff --git a/ydb/library/yql/minikql/mkql_runtime_version.h b/ydb/library/yql/minikql/mkql_runtime_version.h index 6cccfed0c6..168babe974 100644 --- a/ydb/library/yql/minikql/mkql_runtime_version.h +++ b/ydb/library/yql/minikql/mkql_runtime_version.h @@ -24,7 +24,7 @@ namespace NMiniKQL { // 1. Bump this version every time incompatible runtime nodes are introduced. // 2. Make sure you provide runtime node generation for previous runtime versions. #ifndef MKQL_RUNTIME_VERSION -#define MKQL_RUNTIME_VERSION 29U +#define MKQL_RUNTIME_VERSION 30U #endif // History: diff --git a/ydb/library/yql/minikql/ya.make b/ydb/library/yql/minikql/ya.make index c4b608128d..4c0d4d1e28 100644 --- a/ydb/library/yql/minikql/ya.make +++ b/ydb/library/yql/minikql/ya.make @@ -68,6 +68,7 @@ PEERDIR( ydb/library/yql/public/udf ydb/library/yql/public/udf/tz ydb/library/yql/utils + ydb/library/yql/parser/pg_catalog ) IF (MKQL_RUNTIME_VERSION) diff --git a/ydb/library/yql/providers/common/codec/yql_codec.cpp b/ydb/library/yql/providers/common/codec/yql_codec.cpp index 7587e188fa..eb44041cc9 100644 --- a/ydb/library/yql/providers/common/codec/yql_codec.cpp +++ b/ydb/library/yql/providers/common/codec/yql_codec.cpp @@ -132,6 +132,32 @@ void WriteYsonValueImpl(TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& } } break; + case TType::EKind::Pg: + { + auto pgType = AS_TYPE(TPgType, type); + TString ret; + switch (pgType->GetTypeId()) { + case 23: // TODO INT4OID + ret = ToString(value.Get<i32>()); + break; + case 701: // TODO FLOAT8OID + ret = ::FloatToString(value.Get<double>()); + break; + case 25: { + auto datumStart = ((const char*)value.AsBoxed().Get()) + sizeof(NUdf::IBoxedValue) + sizeof(void*); + auto varHdr = (const int*)datumStart; // TODO VARDATA + ui32 len = *varHdr / 4 - sizeof(ui32); + ret = TString((const char*)(varHdr + 1), len); + break; + } + default: + throw yexception() << "Unsupported pg type: " << pgType->GetName(); + } + + writer.OnStringScalar(ret); + return; + } + case TType::EKind::Struct: { writer.OnBeginList(); diff --git a/ydb/library/yql/providers/common/mkql/yql_provider_mkql.cpp b/ydb/library/yql/providers/common/mkql/yql_provider_mkql.cpp index 7be905346b..ed6d5e7ce2 100644 --- a/ydb/library/yql/providers/common/mkql/yql_provider_mkql.cpp +++ b/ydb/library/yql/providers/common/mkql/yql_provider_mkql.cpp @@ -2236,6 +2236,11 @@ TMkqlCommonCallableCompiler::TShared::TShared() { }); }); + AddCallable("PgConst", [](const TExprNode& node, TMkqlBuildContext& ctx) { + auto type = AS_TYPE(TPgType, BuildType(node, *node.GetTypeAnn(), ctx.ProgramBuilder)); + return ctx.ProgramBuilder.PgConst(type, node.Tail().Content()); + }); + AddCallable("QueueCreate", [](const TExprNode& node, TMkqlBuildContext& ctx) { const auto initCapacity = MkqlBuildExpr(*node.Child(1), ctx); const auto initSize = MkqlBuildExpr(*node.Child(2), ctx); diff --git a/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp b/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp index 4ba0e6d740..7cfcf006c6 100644 --- a/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp +++ b/ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp @@ -31,6 +31,11 @@ NKikimr::NMiniKQL::TType* BuildType(const TTypeAnnotationNode& annotation, NKiki } } + case ETypeAnnotationKind::Pg: { + auto pg = annotation.Cast<TPgExprType>(); + return pgmBuilder.NewPgType(pg->GetId()); + } + case ETypeAnnotationKind::Struct: { auto structObj = annotation.Cast<TStructExprType>(); std::vector<std::pair<std::string_view, NKikimr::NMiniKQL::TType*>> members; diff --git a/ydb/library/yql/providers/common/schema/expr/CMakeLists.txt b/ydb/library/yql/providers/common/schema/expr/CMakeLists.txt index 135589f7af..328dce3df6 100644 --- a/ydb/library/yql/providers/common/schema/expr/CMakeLists.txt +++ b/ydb/library/yql/providers/common/schema/expr/CMakeLists.txt @@ -9,6 +9,7 @@ target_link_libraries(common-schema-expr PUBLIC yql-public-udf library-yql-utils common-schema-parser + yql-parser-pg_catalog ) target_sources(common-schema-expr PRIVATE ${CMAKE_SOURCE_DIR}/ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp diff --git a/ydb/library/yql/providers/common/schema/expr/ya.make b/ydb/library/yql/providers/common/schema/expr/ya.make index 60e34bc73a..3a63a305b0 100644 --- a/ydb/library/yql/providers/common/schema/expr/ya.make +++ b/ydb/library/yql/providers/common/schema/expr/ya.make @@ -17,6 +17,7 @@ PEERDIR( ydb/library/yql/public/udf ydb/library/yql/utils ydb/library/yql/providers/common/schema/parser + ydb/library/yql/parser/pg_catalog ) END() diff --git a/ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp b/ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp index 0bbaf5c339..8b71560f75 100644 --- a/ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp +++ b/ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp @@ -5,6 +5,7 @@ #include <ydb/library/yql/ast/yql_expr.h> #include <ydb/library/yql/utils/yql_panic.h> #include <ydb/library/yql/public/udf/udf_data_type.h> +#include <ydb/library/yql/parser/pg_catalog/catalog.h> #include <library/cpp/yson/node/node_io.h> #include <library/cpp/yson/node/node_builder.h> @@ -161,10 +162,14 @@ public: const auto dataType = type->Cast<TDataExprType>(); if (const auto dataParamsType = dynamic_cast<const TDataExprParamsType*>(dataType)) { TBase::SaveDataTypeParams(dataType->GetName(), dataParamsType->GetParamOne(), dataParamsType->GetParamTwo()); - } else + } else { TBase::SaveDataType(dataType->GetName()); } break; + } + case ETypeAnnotationKind::Pg: + TBase::SavePgType(type->Cast<TPgExprType>()->GetName()); + break; case ETypeAnnotationKind::Struct: TBase::SaveStructType(TStructAdaptor(type->Cast<TStructExprType>())); break; @@ -289,6 +294,9 @@ struct TExprTypeLoader { TMaybe<TType> LoadDataType(const TString& dataType, ui32 /*level*/) { return Ctx.MakeType<TDataExprType>(NYql::NUdf::GetDataSlot(dataType)); } + TMaybe<TType> LoadPgType(const TString& name, ui32 /*level*/) { + return Ctx.MakeType<TPgExprType>(NYql::NPg::LookupType(name).TypeId); + } TMaybe<TType> LoadDataTypeParams(const TString& dataType, const TString& paramOne, const TString& paramTwo, ui32 /*level*/) { auto ret = Ctx.MakeType<TDataExprParamsType>(NYql::NUdf::GetDataSlot(dataType), paramOne, paramTwo); YQL_ENSURE(ret->Validate(TPosition(), Ctx)); diff --git a/ydb/library/yql/providers/common/schema/mkql/CMakeLists.txt b/ydb/library/yql/providers/common/schema/mkql/CMakeLists.txt index 85a549aeff..7441990c49 100644 --- a/ydb/library/yql/providers/common/schema/mkql/CMakeLists.txt +++ b/ydb/library/yql/providers/common/schema/mkql/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(common-schema-mkql PUBLIC library-yql-utils providers-common-codec common-schema-parser + yql-parser-pg_catalog ) target_sources(common-schema-mkql PRIVATE ${CMAKE_SOURCE_DIR}/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp diff --git a/ydb/library/yql/providers/common/schema/mkql/ya.make b/ydb/library/yql/providers/common/schema/mkql/ya.make index 2ddbbdb345..c8a756dcef 100644 --- a/ydb/library/yql/providers/common/schema/mkql/ya.make +++ b/ydb/library/yql/providers/common/schema/mkql/ya.make @@ -17,6 +17,7 @@ PEERDIR( ydb/library/yql/utils ydb/library/yql/providers/common/codec ydb/library/yql/providers/common/schema/parser + ydb/library/yql/parser/pg_catalog ) YQL_LAST_ABI_VERSION() diff --git a/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp b/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp index 0a34105714..0fbf1e0ef6 100644 --- a/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp +++ b/ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp @@ -10,6 +10,7 @@ #include <ydb/library/yql/public/udf/udf_type_inspection.h> #include <ydb/library/yql/public/udf/udf_data_type.h> #include <ydb/library/yql/utils/yql_panic.h> +#include <ydb/library/yql/parser/pg_catalog/catalog.h> #include <library/cpp/yson/node/node_io.h> #include <library/cpp/yson/node/node_builder.h> @@ -107,6 +108,11 @@ public: } break; } + case TType::EKind::Pg: { + const auto name = static_cast<const TPgType*>(type)->GetName(); + TBase::SavePgType(name); + break; + } case TType::EKind::Struct: TBase::SaveStructType(*static_cast<const TStructType*>(type)); break; @@ -214,6 +220,11 @@ struct TRuntimeTypeLoader { return Builder.NewDataType(NUdf::GetDataTypeInfo(*slot).TypeId); } + TMaybe<TType> LoadPgType(const TString& pgType, ui32 /*level*/) { + auto typeId = NYql::NPg::LookupType(pgType).TypeId; + return Builder.NewPgType(typeId); + } + TMaybe<TType> LoadDataTypeParams(const TString& dataType, const TString& paramOne, const TString& paramTwo, ui32 /*level*/) { const auto slot = NUdf::FindDataSlot(dataType); if (!slot) { diff --git a/ydb/library/yql/providers/common/schema/parser/yql_type_parser.cpp b/ydb/library/yql/providers/common/schema/parser/yql_type_parser.cpp index ae3f281ed2..cdea80ac96 100644 --- a/ydb/library/yql/providers/common/schema/parser/yql_type_parser.cpp +++ b/ydb/library/yql/providers/common/schema/parser/yql_type_parser.cpp @@ -34,6 +34,13 @@ void TYqlTypeYsonSaverBase::SaveDataType(const TStringBuf& dataType) { Writer.OnEndList(); } +void TYqlTypeYsonSaverBase::SavePgType(const TStringBuf& pgType) { + SaveTypeHeader("PgType"); + Writer.OnListItem(); + Writer.OnStringScalar(pgType); + Writer.OnEndList(); +} + void TYqlTypeYsonSaverBase::SaveDataTypeParams(const TStringBuf& dataType, const TStringBuf& paramOne, const TStringBuf& paramTwo) { SaveTypeHeader("DataType"); Writer.OnListItem(); diff --git a/ydb/library/yql/providers/common/schema/parser/yql_type_parser.h b/ydb/library/yql/providers/common/schema/parser/yql_type_parser.h index a3116efb14..b9fb342914 100644 --- a/ydb/library/yql/providers/common/schema/parser/yql_type_parser.h +++ b/ydb/library/yql/providers/common/schema/parser/yql_type_parser.h @@ -31,6 +31,7 @@ protected: void SaveEmptyListType(); void SaveEmptyDictType(); void SaveDataType(const TStringBuf& dataType); + void SavePgType(const TStringBuf& pgType); void SaveDataTypeParams(const TStringBuf& dataType, const TStringBuf& paramOne, const TStringBuf& paramTwo); void SaveResourceType(const TStringBuf& tag); @@ -232,6 +233,12 @@ TMaybe<typename TLoader::TType> DoLoadTypeFromYson(TLoader& loader, const NYT::T } return loader.LoadDataTypeParams(node[1].AsString(), node[2].AsString(), node[3].AsString(), level); + } else if (typeName == "PgType") { + if (node.Size() != 2 || !node[1].IsString()) { + loader.Error("Invalid pg type scheme"); + return Nothing(); + } + return loader.LoadPgType(node[1].AsString(), level); } else if (typeName == "ResourceType") { if (node.Size() != 2 || !node[1].IsString()) { loader.Error("Invalid resource type scheme"); diff --git a/ydb/library/yql/providers/common/schema/skiff/yql_skiff_schema.cpp b/ydb/library/yql/providers/common/schema/skiff/yql_skiff_schema.cpp index 2461a17094..c814cc5ae2 100644 --- a/ydb/library/yql/providers/common/schema/skiff/yql_skiff_schema.cpp +++ b/ydb/library/yql/providers/common/schema/skiff/yql_skiff_schema.cpp @@ -84,6 +84,10 @@ struct TSkiffTypeLoader { ythrow yexception() << "Unsupported data type" << NUdf::GetDataTypeInfo(*slot).Name; } + TMaybe<TType> LoadPgType(const TString& /*pgType*/, ui32 /*level*/) { + ythrow yexception() << "Unsupported PG type"; + } + TMaybe<TType> LoadDataTypeParams(const TString& dataType, const TString& paramOne, const TString& /*paramTwo*/, ui32 /*level*/) { const auto slot = NUdf::FindDataSlot(dataType); if (!slot) { diff --git a/ydb/library/yql/providers/common/schema/yql_schema_utils.cpp b/ydb/library/yql/providers/common/schema/yql_schema_utils.cpp index c8372260ac..3f92d2878f 100644 --- a/ydb/library/yql/providers/common/schema/yql_schema_utils.cpp +++ b/ydb/library/yql/providers/common/schema/yql_schema_utils.cpp @@ -49,7 +49,7 @@ bool EqualsYsonTypesIgnoreStructOrder(const NYT::TNode& left, const NYT::TNode& return true; } else if (typeName == "EmptyDictType") { return true; - } else if (typeName == "DataType") { + } else if (typeName == "DataType" || typeName == "PgType") { return left == right; } else if (typeName == "ResourceType") { return left[1].AsString() == right[1].AsString(); diff --git a/ydb/library/yql/providers/config/yql_config_provider.cpp b/ydb/library/yql/providers/config/yql_config_provider.cpp index 6952e96cf0..3df2eba81c 100644 --- a/ydb/library/yql/providers/config/yql_config_provider.cpp +++ b/ydb/library/yql/providers/config/yql_config_provider.cpp @@ -735,6 +735,14 @@ namespace { Types.OrderedColumns = (name == "OrderedColumns"); } + else if (name == "PgTypes" || name == "DisablePgTypes") { + if (args.size() != 0) { + ctx.AddError(TIssue(pos, TStringBuilder() << "Expected no arguments, but got " << args.size())); + return false; + } + + Types.PgTypes = (name == "PgTypes"); + } else if (name == "FolderSubDirsLimit") { if (args.size() != 1) { ctx.AddError(TIssue(pos, TStringBuilder() << "Expected 1 argument, but got " << args.size())); diff --git a/ydb/library/yql/sql/pg/pg_sql.cpp b/ydb/library/yql/sql/pg/pg_sql.cpp index 354b4d4dc4..0b0a4aec0d 100644 --- a/ydb/library/yql/sql/pg/pg_sql.cpp +++ b/ydb/library/yql/sql/pg/pg_sql.cpp @@ -147,6 +147,11 @@ public: auto configSource = L(A("DataSource"), QA(TString(NYql::ConfigProviderName))); Statements.push_back(L(A("let"), A("world"), L(A(TString(NYql::ConfigureName)), A("world"), configSource, QA("OrderedColumns")))); + if (Settings.PgTypes) { + Statements.push_back(L(A("let"), A("world"), L(A(TString(NYql::ConfigureName)), A("world"), configSource, + QA("PgTypes")))); + } + if (DqEngineEnabled) { Statements.push_back(L(A("let"), A("world"), L(A(TString(NYql::ConfigureName)), A("world"), configSource, QA("DqEngine"), QA(DqEngineForce ? "force" : "auto")))); @@ -815,13 +820,19 @@ public: const auto& val = value->val; switch (NodeTag(val)) { case T_Integer: { - return L(A("Just"), L(A("Int32"), QA(ToString(IntVal(val))))); + return Settings.PgTypes ? + L(A("PgConst"), QA("int4"), QA(ToString(IntVal(val)))) : + L(A("Just"), L(A("Int32"), QA(ToString(IntVal(val))))); } case T_Float: { - return L(A("Just"), L(A("Double"), QA(ToString(StrFloatVal(val))))); + return Settings.PgTypes ? + L(A("PgConst"), QA("float8"), QA(ToString(StrFloatVal(val)))) : + L(A("Just"), L(A("Double"), QA(ToString(StrFloatVal(val))))); } case T_String: { - return L(A("Just"), L(A("Utf8"), QA(ToString(StrVal(val))))); + return Settings.PgTypes ? + L(A("PgConst"), QA("text"), QA(ToString(StrVal(val)))) : + L(A("Just"), L(A("Utf8"), QA(ToString(StrVal(val))))); } case T_Null: { return L(A("Null")); diff --git a/ydb/library/yql/sql/settings/translation_settings.cpp b/ydb/library/yql/sql/settings/translation_settings.cpp index e09fd43aaa..a472588cf3 100644 --- a/ydb/library/yql/sql/settings/translation_settings.cpp +++ b/ydb/library/yql/sql/settings/translation_settings.cpp @@ -37,6 +37,7 @@ namespace NSQLTranslation { , SyntaxVersion(0) , AnsiLexer(false) , PgParser(false) + , PgTypes(false) , InferSyntaxVersion(false) , V0Behavior(EV0Behavior::Silent) , V0ForceDisable(InTestEnvironment()) @@ -105,6 +106,9 @@ namespace NSQLTranslation { settings.AnsiLexer = true; } else if (value == "syntax_pg") { settings.PgParser = true; + } else if (value == "syntax_pg_types") { + settings.PgParser = true; + settings.PgTypes = true; } else { issues.AddIssue(NYql::YqlIssue(NYql::TPosition(0, lineNumber), NYql::TIssuesIds::DEFAULT_ERROR, TStringBuilder() << "Unknown SQL translation setting: " << value)); diff --git a/ydb/library/yql/sql/settings/translation_settings.h b/ydb/library/yql/sql/settings/translation_settings.h index 0b9194a249..4f268a4f3c 100644 --- a/ydb/library/yql/sql/settings/translation_settings.h +++ b/ydb/library/yql/sql/settings/translation_settings.h @@ -75,6 +75,7 @@ namespace NSQLTranslation { ui16 SyntaxVersion; bool AnsiLexer; bool PgParser; + bool PgTypes; bool InferSyntaxVersion; EV0Behavior V0Behavior; bool V0ForceDisable; |