aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvvvv <vvvv@yandex-team.ru>2022-02-25 04:31:17 +0300
committervvvv <vvvv@yandex-team.ru>2022-02-25 04:31:17 +0300
commit66834feb30614a28410b37b4be1842f6eb9fc7ed (patch)
tree382c6fbe2ecc9271900888e86076ad0e5d2776bf
parent0d27a6699fbcf898a0c322d3eb845fffd711a0f1 (diff)
downloadydb-66834feb30614a28410b37b4be1842f6eb9fc7ed.tar.gz
YQL-13710 initial runtime support for PgConst, introduced PgType in Expr/Mkql types
ref:e65ae23014cb20961183f1f49314023cdc9259a2
-rw-r--r--CMakeLists.txt2
-rw-r--r--ydb/core/yq/libs/pretty_printers/minikql_program_printer.cpp3
-rw-r--r--ydb/library/yql/ast/CMakeLists.txt1
-rw-r--r--ydb/library/yql/ast/ya.make1
-rw-r--r--ydb/library/yql/ast/yql_expr.cpp30
-rw-r--r--ydb/library/yql/ast/yql_expr.h41
-rw-r--r--ydb/library/yql/ast/yql_expr_types.h3
-rw-r--r--ydb/library/yql/ast/yql_type_string.cpp4
-rw-r--r--ydb/library/yql/core/type_ann/CMakeLists.txt1
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_core.cpp21
-rw-r--r--ydb/library/yql/core/type_ann/ya.make1
-rw-r--r--ydb/library/yql/core/yql_type_annotation.h2
-rw-r--r--ydb/library/yql/dq/runtime/dq_arrow_helpers.cpp1
-rw-r--r--ydb/library/yql/dq/runtime/dq_transport.cpp1
-rw-r--r--ydb/library/yql/minikql/CMakeLists.txt1
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp4
-rw-r--r--ydb/library/yql/minikql/mkql_node.cpp38
-rw-r--r--ydb/library/yql/minikql/mkql_node.h32
-rw-r--r--ydb/library/yql/minikql/mkql_node_cast.cpp1
-rw-r--r--ydb/library/yql/minikql/mkql_node_printer.cpp7
-rw-r--r--ydb/library/yql/minikql/mkql_node_printer_ut.cpp1
-rw-r--r--ydb/library/yql/minikql/mkql_node_serialization.cpp33
-rw-r--r--ydb/library/yql/minikql/mkql_node_visitor.cpp13
-rw-r--r--ydb/library/yql/minikql/mkql_node_visitor.h4
-rw-r--r--ydb/library/yql/minikql/mkql_program_builder.cpp15
-rw-r--r--ydb/library/yql/minikql/mkql_program_builder.h3
-rw-r--r--ydb/library/yql/minikql/mkql_runtime_version.h2
-rw-r--r--ydb/library/yql/minikql/ya.make1
-rw-r--r--ydb/library/yql/providers/common/codec/yql_codec.cpp26
-rw-r--r--ydb/library/yql/providers/common/mkql/yql_provider_mkql.cpp5
-rw-r--r--ydb/library/yql/providers/common/mkql/yql_type_mkql.cpp5
-rw-r--r--ydb/library/yql/providers/common/schema/expr/CMakeLists.txt1
-rw-r--r--ydb/library/yql/providers/common/schema/expr/ya.make1
-rw-r--r--ydb/library/yql/providers/common/schema/expr/yql_expr_schema.cpp10
-rw-r--r--ydb/library/yql/providers/common/schema/mkql/CMakeLists.txt1
-rw-r--r--ydb/library/yql/providers/common/schema/mkql/ya.make1
-rw-r--r--ydb/library/yql/providers/common/schema/mkql/yql_mkql_schema.cpp11
-rw-r--r--ydb/library/yql/providers/common/schema/parser/yql_type_parser.cpp7
-rw-r--r--ydb/library/yql/providers/common/schema/parser/yql_type_parser.h7
-rw-r--r--ydb/library/yql/providers/common/schema/skiff/yql_skiff_schema.cpp4
-rw-r--r--ydb/library/yql/providers/common/schema/yql_schema_utils.cpp2
-rw-r--r--ydb/library/yql/providers/config/yql_config_provider.cpp8
-rw-r--r--ydb/library/yql/sql/pg/pg_sql.cpp17
-rw-r--r--ydb/library/yql/sql/settings/translation_settings.cpp4
-rw-r--r--ydb/library/yql/sql/settings/translation_settings.h1
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;