summaryrefslogtreecommitdiffstats
path: root/yql/essentials/parser/pg_wrapper/interface
diff options
context:
space:
mode:
authorvvvv <[email protected]>2024-11-06 23:54:28 +0300
committervvvv <[email protected]>2024-11-07 00:04:25 +0300
commitcf2a23963ac10add28c50cc114fbf48953eca5aa (patch)
tree174b849b8ecfa96b0c8e4409ab3287721a9210c8 /yql/essentials/parser/pg_wrapper/interface
parent3a3113a2bf5a7fab32bde414932082b264c559fc (diff)
Prepare move yql/minikql YQL-19206
types,jsonpath,dom commit_hash:6b54be5968b6a30b6d97fe3a1611574bcefc749e
Diffstat (limited to 'yql/essentials/parser/pg_wrapper/interface')
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/arrow.h23
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/codec.h54
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/comp_factory.h20
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/compare.h19
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/config.h8
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/context.h26
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/interface.cpp207
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/interface.h13
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/optimizer.h80
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/pack.h32
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/parser.h20
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/raw_parser.h25
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/type_desc.h52
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/utils.h20
-rw-r--r--yql/essentials/parser/pg_wrapper/interface/ya.make27
15 files changed, 626 insertions, 0 deletions
diff --git a/yql/essentials/parser/pg_wrapper/interface/arrow.h b/yql/essentials/parser/pg_wrapper/interface/arrow.h
new file mode 100644
index 00000000000..a831b1bfea9
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/arrow.h
@@ -0,0 +1,23 @@
+#pragma once
+#include <contrib/ydb/library/yql/minikql/mkql_node.h>
+#include <yql/essentials/public/udf/arrow/block_item.h>
+#include <arrow/datum.h>
+
+namespace NYql {
+
+arrow::Datum MakePgScalar(NKikimr::NMiniKQL::TPgType* type, const NKikimr::NUdf::TUnboxedValuePod& value, arrow::MemoryPool& pool);
+arrow::Datum MakePgScalar(NKikimr::NMiniKQL::TPgType* type, const NUdf::TBlockItem& value, arrow::MemoryPool& pool);
+
+using TColumnConverter = std::function<std::shared_ptr<arrow::Array>(const std::shared_ptr<arrow::Array>&)>;
+TColumnConverter BuildPgColumnConverter(const std::shared_ptr<arrow::DataType>& originalType, NKikimr::NMiniKQL::TPgType* targetType);
+
+} // NYql
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+class IBlockAggregatorFactory;
+void RegisterPgBlockAggs(THashMap<TString, std::unique_ptr<IBlockAggregatorFactory>>& registry);
+
+}
+} \ No newline at end of file
diff --git a/yql/essentials/parser/pg_wrapper/interface/codec.h b/yql/essentials/parser/pg_wrapper/interface/codec.h
new file mode 100644
index 00000000000..c2aa3c4af0d
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/codec.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <yql/essentials/public/udf/udf_value.h>
+
+#include <util/generic/strbuf.h>
+#include <util/generic/string.h>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+class TPgType;
+
+} // NMiniKQL
+} // NKikimr
+
+namespace NYql {
+namespace NResult {
+class TYsonResultWriter;
+}
+
+namespace NCommon {
+
+class TInputBuf;
+class TOutputBuf;
+
+TString PgValueToString(const NUdf::TUnboxedValuePod& value, ui32 pgTypeId);
+NUdf::TUnboxedValue PgValueFromString(const TStringBuf text, ui32 pgTypeId);
+
+TString PgValueToNativeText(const NUdf::TUnboxedValuePod& value, ui32 pgTypeId);
+NUdf::TUnboxedValue PgValueFromNativeText(const TStringBuf text, ui32 pgTypeId);
+
+TString PgValueToNativeBinary(const NUdf::TUnboxedValuePod& value, ui32 pgTypeId);
+NUdf::TUnboxedValue PgValueFromNativeBinary(const TStringBuf binary, ui32 pgTypeId);
+
+TString PgValueCoerce(const NUdf::TUnboxedValuePod& value, ui32 pgTypeId, i32 typMod, TMaybe<TString>* error);
+
+void WriteYsonValuePg(NResult::TYsonResultWriter& writer, const NUdf::TUnboxedValuePod& value, NKikimr::NMiniKQL::TPgType* type,
+ const TVector<ui32>* structPositions);
+
+void WriteYsonValueInTableFormatPg(TOutputBuf& buf, NKikimr::NMiniKQL::TPgType* type, const NKikimr::NUdf::TUnboxedValuePod& value, bool topLevel);
+
+NUdf::TUnboxedValue ReadYsonValueInTableFormatPg(NKikimr::NMiniKQL::TPgType* type, char cmd, TInputBuf& buf);
+NUdf::TUnboxedValue ReadYsonValuePg(NKikimr::NMiniKQL::TPgType* type, char cmd, TInputBuf& buf);
+
+void SkipSkiffPg(NKikimr::NMiniKQL::TPgType* type, TInputBuf& buf);
+
+NKikimr::NUdf::TUnboxedValue ReadSkiffPg(NKikimr::NMiniKQL::TPgType* type, TInputBuf& buf);
+void WriteSkiffPg(NKikimr::NMiniKQL::TPgType* type, const NKikimr::NUdf::TUnboxedValuePod& value, TOutputBuf& buf);
+
+extern "C" void ReadSkiffPgValue(NKikimr::NMiniKQL::TPgType* type, NKikimr::NUdf::TUnboxedValue& value, TInputBuf& buf);
+extern "C" void WriteSkiffPgValue(NKikimr::NMiniKQL::TPgType* type, const NKikimr::NUdf::TUnboxedValuePod& value, TOutputBuf& buf);
+
+} // namespace NCommon
+} // namespace NYql
diff --git a/yql/essentials/parser/pg_wrapper/interface/comp_factory.h b/yql/essentials/parser/pg_wrapper/interface/comp_factory.h
new file mode 100644
index 00000000000..e969c6e1c69
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/comp_factory.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <functional>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+class IComputationNode;
+class TCallable;
+struct TComputationNodeFactoryContext;
+
+} // NMiniKQL
+} // NKikimr
+
+namespace NYql {
+
+std::function<NKikimr::NMiniKQL::IComputationNode* (NKikimr::NMiniKQL::TCallable&,
+ const NKikimr::NMiniKQL::TComputationNodeFactoryContext&)> GetPgFactory();
+
+} // NYql
diff --git a/yql/essentials/parser/pg_wrapper/interface/compare.h b/yql/essentials/parser/pg_wrapper/interface/compare.h
new file mode 100644
index 00000000000..233218e0c29
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/compare.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include <yql/essentials/public/udf/udf_type_builder.h>
+#include <yql/essentials/public/udf/arrow/block_item_comparator.h>
+#include <yql/essentials/public/udf/arrow/block_item_hasher.h>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+class TPgType;
+
+NUdf::IHash::TPtr MakePgHash(const TPgType* type);
+NUdf::ICompare::TPtr MakePgCompare(const TPgType* type);
+NUdf::IEquate::TPtr MakePgEquate(const TPgType* type);
+NUdf::IBlockItemComparator::TPtr MakePgItemComparator(ui32 typeId);
+NUdf::IBlockItemHasher::TPtr MakePgItemHasher(ui32 typeId);
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/yql/essentials/parser/pg_wrapper/interface/config.h b/yql/essentials/parser/pg_wrapper/interface/config.h
new file mode 100644
index 00000000000..3cf3fcda9fa
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/config.h
@@ -0,0 +1,8 @@
+#include <util/generic/fwd.h>
+
+namespace NYql {
+
+TString GetPostgresServerVersionNum();
+TString GetPostgresServerVersionStr();
+
+} // NYql \ No newline at end of file
diff --git a/yql/essentials/parser/pg_wrapper/interface/context.h b/yql/essentials/parser/pg_wrapper/interface/context.h
new file mode 100644
index 00000000000..127fcfa3880
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/context.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <string_view>
+#include <yql/essentials/core/pg_settings/guc_settings.h>
+#include <yql/essentials/parser/pg_catalog/catalog.h>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+void* PgInitializeMainContext();
+void PgDestroyMainContext(void* ctx);
+
+void PgAcquireThreadContext(void* ctx);
+void PgReleaseThreadContext(void* ctx);
+
+std::unique_ptr<NYql::NPg::IExtensionLoader> CreateExtensionLoader();
+
+void* PgInitializeContext(const std::string_view& contextType);
+void PgDestroyContext(const std::string_view& contextType, void* ctx);
+
+void PgSetGUCSettings(void* ctx, const TGUCSettings::TPtr& GUCSettings);
+std::optional<std::string> PGGetGUCSetting(const std::string& key);
+
+void PgCreateSysCacheEntries(void* ctx);
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/yql/essentials/parser/pg_wrapper/interface/interface.cpp b/yql/essentials/parser/pg_wrapper/interface/interface.cpp
new file mode 100644
index 00000000000..738ed46b19b
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/interface.cpp
@@ -0,0 +1,207 @@
+#include "interface.h"
+
+#include <array>
+
+#include <util/string/builder.h>
+#include <util/generic/hash.h>
+#include <util/generic/hash_set.h>
+
+#include <library/cpp/disjoint_sets/disjoint_sets.h>
+
+namespace NYql {
+
+namespace {
+
+std::array<TStringBuf,6> Prefixes = {
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ " "
+};
+
+TStringBuf Prefix(int level) {
+ return level < (int)Prefixes.size()
+ ? Prefixes[level]
+ : Prefixes.back();
+}
+
+void PrettyPrintVar(TStringBuilder& b, const IOptimizer::TInput* input, IOptimizer::TVarId varId) {
+ const auto& [relno, varno] = varId;
+ auto varName = input
+ ? input->Rels[relno-1].TargetVars[varno-1].Name
+ : '\0';
+ if (!varName) {
+ b << "(" << relno << "," << varno << ")";
+ } else {
+ b << varName;
+ }
+}
+
+void PrettyPrintVars(TStringBuilder& b, const IOptimizer::TInput* input, const std::vector<IOptimizer::TVarId>& vars) {
+ for (ui32 j = 0; j < vars.size(); ++j) {
+ PrettyPrintVar(b, input, vars[j]);
+ if (j != vars.size() - 1) {
+ b << ",";
+ }
+ }
+}
+
+void PrettyPrintNode(int level, TStringBuilder& b, const IOptimizer::TOutput& output, int id) {
+ TStringBuf prefix = Prefix(level);
+ const auto& node = output.Nodes[id];
+ switch (node.Mode) {
+ case IOptimizer::EJoinType::Unknown: b << prefix << " Node\n"; break;
+ case IOptimizer::EJoinType::Inner: b << prefix << " Inner Join\n"; break;
+ case IOptimizer::EJoinType::Left: b << prefix << " Left Join\n"; break;
+ case IOptimizer::EJoinType::Right: b << prefix << " Right Join\n"; break;
+ default: b << prefix << " Unknown\n"; break;
+ }
+ switch (node.Strategy) {
+ case IOptimizer::EJoinStrategy::Hash: b << prefix << " Hash Strategy\n"; break;
+ case IOptimizer::EJoinStrategy::Loop: b << prefix << " Loop Strategy\n"; break;
+ default: break;
+ }
+ if (!node.Rels.empty())
+ {
+ b << prefix << " Rels: [";
+ for (int i = 0; i < (int)node.Rels.size()-1; i++) {
+ b << node.Rels[i] << ",";
+ }
+ b << node.Rels.back();
+ b << "]\n";
+ }
+
+ {
+ if (!node.LeftVars.empty() && !node.RightVars.empty()) {
+ b << prefix << " Op: ";
+ PrettyPrintVars(b, output.Input, node.LeftVars);
+ b << " = ";
+ PrettyPrintVars(b, output.Input, node.RightVars);
+ b << "\n";
+ }
+ }
+
+ if (node.Outer != -1) {
+ b << prefix << " {\n";
+ PrettyPrintNode(level+1, b, output, node.Outer);
+ b << prefix << " }\n";
+ }
+ if (node.Inner != -1) {
+ b << prefix << " {\n";
+ PrettyPrintNode(level+1, b, output, node.Inner);
+ b << prefix << " }\n";
+ }
+}
+
+void PrettyPrintRel(TStringBuilder& b, const IOptimizer::TInput* input, const auto& relId) {
+ const auto& rel = input->Rels[relId - 1];
+ b << "{";
+ b << "rows: " << rel.Rows << ",";
+ b << "cost: " << rel.TotalCost << ",";
+ b << "vars: [";
+ for (ui32 i = 0; i < rel.TargetVars.size(); i++) {
+ PrettyPrintVar(b, input, {relId, i + 1});
+ if (i != rel.TargetVars.size() - 1) {
+ b << ", ";
+ }
+ }
+ b << "]";
+ b << "}";
+}
+
+} // namespace
+
+TString IOptimizer::TOutput::ToString(bool printCost) const {
+ TStringBuilder b;
+ if (printCost) {
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "%.2lf", Rows);
+ b << "Rows: " << buf << "\n";
+ snprintf(buf, sizeof(buf), "%.2lf", TotalCost);
+ b << "TotalCost: " << buf << "\n";
+ }
+ b << "{\n";
+ if (!Nodes.empty()) {
+ PrettyPrintNode(0, b, *this, 0);
+ }
+ b << "}\n";
+ return b;
+}
+
+TString IOptimizer::TInput::ToString() const {
+ TStringBuilder b;
+ b << "Rels: [";
+ for (ui32 i = 0; i < Rels.size(); ++i) {
+ PrettyPrintRel(b, this, i + 1);
+ if (i != Rels.size() - 1) {
+ b << ",\n";
+ }
+ }
+ b << "]\n";
+ b << "EqClasses: [";
+ for (ui32 i = 0; i < EqClasses.size(); ++i) {
+ b << "[";
+ PrettyPrintVars(b, this, EqClasses[i].Vars);
+ b << "]";
+ if (i != EqClasses.size() - 1) {
+ b << ",";
+ }
+ }
+ b << "]\n";
+ return b;
+}
+
+void IOptimizer::TInput::Normalize() {
+ using TId = TDisjointSets::TElement;
+
+ THashMap<TVarId, TId> var2id;
+ std::vector<TVarId> id2var;
+ TId curId = 1;
+
+ for (auto& eq : EqClasses) {
+ for (auto& v : eq.Vars) {
+ auto& id = var2id[v];
+ if (id == 0) {
+ id = curId;
+ id2var.resize(curId + 1);
+ id2var[curId] = v;
+ ++curId;
+ }
+ }
+ }
+
+ TDisjointSets u(curId + 1);
+ for (auto& eq : EqClasses) {
+ Y_ABORT_UNLESS(!eq.Vars.empty());
+
+ ui32 i = 0;
+ TId first = var2id[eq.Vars[i++]];
+ for (; i < eq.Vars.size(); ++i) {
+ TId id = var2id[eq.Vars[i]];
+ u.UnionSets(first, id);
+ }
+ }
+
+ THashMap<TId, THashSet<TId>> eqClasses;
+ for (auto& eq : EqClasses) {
+ for (auto& var : eq.Vars) {
+ auto id = var2id[var];
+ auto canonicalId = u.CanonicSetElement(id);
+ eqClasses[canonicalId].emplace(id);
+ }
+ }
+ EqClasses.clear();
+ for (auto& [_, ids]: eqClasses) {
+ TEq eqClass;
+ eqClass.Vars.reserve(ids.size());
+ for (auto id : ids) {
+ eqClass.Vars.emplace_back(id2var[id]);
+ }
+ std::sort(eqClass.Vars.begin(), eqClass.Vars.end());
+ EqClasses.emplace_back(std::move(eqClass));
+ }
+}
+
+}
diff --git a/yql/essentials/parser/pg_wrapper/interface/interface.h b/yql/essentials/parser/pg_wrapper/interface/interface.h
new file mode 100644
index 00000000000..269d7ea2794
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/interface.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "arrow.h"
+#include "codec.h"
+#include "config.h"
+#include "compare.h"
+#include "comp_factory.h"
+#include "context.h"
+#include "pack.h"
+#include "parser.h"
+#include "type_desc.h"
+#include "utils.h"
+#include "optimizer.h"
diff --git a/yql/essentials/parser/pg_wrapper/interface/optimizer.h b/yql/essentials/parser/pg_wrapper/interface/optimizer.h
new file mode 100644
index 00000000000..689d2f622f9
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/optimizer.h
@@ -0,0 +1,80 @@
+#pragma once
+
+#include <yql/essentials/core/cbo/cbo_optimizer_new.h>
+
+#include <functional>
+
+namespace NYql {
+
+struct TExprContext;
+
+struct IOptimizer {
+ using TVarId = std::tuple<int, int>;
+
+ struct TVar {
+ char Name = 0; // debug name: 'a', 'b', 'c', ...
+ };
+
+ struct TRel {
+ double Rows = 0;
+ double TotalCost = 0;
+
+ std::vector<TVar> TargetVars;
+ };
+
+ struct TEq {
+ std::vector<TVarId> Vars;
+ };
+
+ struct TInput {
+ std::vector<TRel> Rels;
+ std::vector<TEq> EqClasses;
+ std::vector<TEq> Left;
+ std::vector<TEq> Right;
+
+ TString ToString() const;
+ void Normalize();
+ };
+
+ enum class EJoinType {
+ Unknown,
+ Inner,
+ Left,
+ Right,
+ };
+
+ enum class EJoinStrategy {
+ Unknown,
+ Hash,
+ Loop
+ };
+
+ struct TJoinNode {
+ EJoinType Mode = EJoinType::Unknown;
+ EJoinStrategy Strategy = EJoinStrategy::Unknown;
+ // only a = b && c = d ... supported yet
+ std::vector<TVarId> LeftVars = {};
+ std::vector<TVarId> RightVars = {};
+ std::vector<int> Rels = {};
+ int Outer = -1; // index in Nodes
+ int Inner = -1; // index in Nodes
+ };
+
+ struct TOutput {
+ std::vector<TJoinNode> Nodes;
+ TInput* Input = nullptr;
+ double Rows = 0;
+ double TotalCost = 0;
+
+ TString ToString(bool printCost = true) const;
+ };
+
+ virtual ~IOptimizer() = default;
+ virtual TOutput JoinSearch() = 0;
+};
+
+IOptimizer* MakePgOptimizerInternal(const IOptimizer::TInput& input, const std::function<void(const TString&)>& log = {});
+
+IOptimizerNew* MakePgOptimizerNew(IProviderContext& pctx, TExprContext& ctx, const std::function<void(const TString&)>& log = {});
+
+} // namespace NYql
diff --git a/yql/essentials/parser/pg_wrapper/interface/pack.h b/yql/essentials/parser/pg_wrapper/interface/pack.h
new file mode 100644
index 00000000000..281f8139c48
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/pack.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <yql/essentials/public/udf/udf_value.h>
+
+#include <util/generic/buffer.h>
+#include <util/generic/strbuf.h>
+#include <util/generic/vector.h>
+
+namespace NKikimr {
+namespace NMiniKQL {
+
+class TPgType;
+class TPagedBuffer;
+namespace NDetails {
+class TChunkedInputBuffer;
+}
+
+void PGPackImpl(bool stable, const TPgType* type, const NUdf::TUnboxedValuePod& value, TBuffer& buf);
+void PGPackImpl(bool stable, const TPgType* type, const NUdf::TUnboxedValuePod& value, TPagedBuffer& buf);
+
+NUdf::TUnboxedValue PGUnpackImpl(const TPgType* type, TStringBuf& buf);
+NUdf::TUnboxedValue PGUnpackImpl(const TPgType* type, NDetails::TChunkedInputBuffer& buf);
+
+void EncodePresortPGValue(TPgType* type, const NUdf::TUnboxedValue& value, TVector<ui8>& output);
+NUdf::TUnboxedValue DecodePresortPGValue(TPgType* type, TStringBuf& input, TVector<ui8>& buffer);
+
+ui64 PgValueSize(const NUdf::TUnboxedValuePod& value, i32 typeLen);
+ui64 PgValueSize(ui32 pgTypeId, const NUdf::TUnboxedValuePod& value);
+ui64 PgValueSize(const TPgType* type, const NUdf::TUnboxedValuePod& value);
+
+} // namespace NMiniKQL
+} // namespace NKikimr
diff --git a/yql/essentials/parser/pg_wrapper/interface/parser.h b/yql/essentials/parser/pg_wrapper/interface/parser.h
new file mode 100644
index 00000000000..f86fee16302
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/parser.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <yql/essentials/ast/yql_ast.h>
+#include <yql/essentials/parser/pg_catalog/catalog.h>
+
+namespace NSQLTranslation {
+
+struct TTranslationSettings;
+
+} // NSQLTranslation
+
+namespace NSQLTranslationPG {
+
+NYql::TAstParseResult PGToYql(const TString& query, const NSQLTranslation::TTranslationSettings& settings, NYql::TStmtParseInfo* stmtParseInfo = nullptr);
+TVector<NYql::TAstParseResult> PGToYqlStatements(const TString& query, const NSQLTranslation::TTranslationSettings& settings, TVector<NYql::TStmtParseInfo>* stmtParseInfo = nullptr);
+std::unique_ptr<NYql::NPg::IExtensionSqlParser> CreateExtensionSqlParser();
+std::unique_ptr<NYql::NPg::ISystemFunctionsParser> CreateSystemFunctionsParser();
+std::unique_ptr<NYql::NPg::ISqlLanguageParser> CreateSqlLanguageParser();
+
+} // NSQLTranslationPG
diff --git a/yql/essentials/parser/pg_wrapper/interface/raw_parser.h b/yql/essentials/parser/pg_wrapper/interface/raw_parser.h
new file mode 100644
index 00000000000..b0b47177067
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/raw_parser.h
@@ -0,0 +1,25 @@
+#pragma once
+
+extern "C" {
+struct List;
+struct Node;
+}
+
+#include <yql/essentials/public/issue/yql_issue.h>
+
+namespace NYql {
+
+class IPGParseEvents {
+public:
+ virtual ~IPGParseEvents() = default;
+ virtual void OnResult(const List* raw) = 0;
+ virtual void OnError(const TIssue& issue) = 0;
+};
+
+TString PrintPGTree(const List* raw);
+
+TString GetCommandName(Node* node);
+
+void PGParse(const TString& input, IPGParseEvents& events);
+
+}
diff --git a/yql/essentials/parser/pg_wrapper/interface/type_desc.h b/yql/essentials/parser/pg_wrapper/interface/type_desc.h
new file mode 100644
index 00000000000..f50c3a33e4b
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/type_desc.h
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <util/generic/strbuf.h>
+#include <util/generic/maybe.h>
+
+namespace NKikimr::NPg {
+
+struct ITypeDesc;
+
+ui32 PgTypeIdFromTypeDesc(const ITypeDesc* typeDesc);
+const ITypeDesc* TypeDescFromPgTypeId(ui32 pgTypeId);
+
+TString PgTypeNameFromTypeDesc(const ITypeDesc* typeDesc, const TString& typeMod = {});
+const ITypeDesc* TypeDescFromPgTypeName(const TStringBuf name);
+TString TypeModFromPgTypeName(const TStringBuf name);
+
+bool TypeDescIsComparable(const ITypeDesc* typeDesc);
+i32 TypeDescGetTypeLen(const ITypeDesc* typeDesc);
+ui32 TypeDescGetStoredSize(const ITypeDesc* typeDesc);
+bool TypeDescNeedsCoercion(const ITypeDesc* typeDesc);
+
+int PgNativeBinaryCompare(const char* dataL, size_t sizeL, const char* dataR, size_t sizeR, const ITypeDesc* typeDesc);
+
+ui64 PgNativeBinaryHash(const char* data, size_t size, const ITypeDesc* typeDesc);
+
+struct TTypeModResult {
+ i32 Typmod = -1;
+ TMaybe<TString> Error;
+};
+
+TTypeModResult BinaryTypeModFromTextTypeMod(const TString& str, const ITypeDesc* typeDesc);
+
+TMaybe<TString> PgNativeBinaryValidate(const TStringBuf binary, const ITypeDesc* typeDesc);
+
+struct TCoerceResult {
+ TMaybe<TString> NewValue;
+ TMaybe<TString> Error;
+};
+
+TCoerceResult PgNativeBinaryCoerce(const TStringBuf binary, const ITypeDesc* typeDesc, i32 typmod);
+
+struct TConvertResult {
+ TString Str;
+ TMaybe<TString> Error;
+};
+
+TConvertResult PgNativeBinaryFromNativeText(const TString& str, const ITypeDesc* typeDesc);
+TConvertResult PgNativeBinaryFromNativeText(const TString& str, ui32 pgTypeId);
+TConvertResult PgNativeTextFromNativeBinary(const TStringBuf binary, const ITypeDesc* typeDesc);
+TConvertResult PgNativeTextFromNativeBinary(const TStringBuf binary, ui32 pgTypeId);
+
+} // namespace NKikimr::NPg
diff --git a/yql/essentials/parser/pg_wrapper/interface/utils.h b/yql/essentials/parser/pg_wrapper/interface/utils.h
new file mode 100644
index 00000000000..c3197f86ad5
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/utils.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <yql/essentials/public/udf/udf_data_type.h>
+#include <yql/essentials/public/udf/udf_value_builder.h>
+
+#include <util/generic/maybe.h>
+
+namespace NYql {
+
+ui32 ConvertToPgType(NKikimr::NUdf::EDataSlot slot);
+TMaybe<NKikimr::NUdf::EDataSlot> ConvertFromPgType(ui32 typeId);
+
+bool ParsePgIntervalModifier(const TString& str, i32& ret);
+
+std::unique_ptr<NUdf::IPgBuilder> CreatePgBuilder();
+bool HasPgKernel(ui32 procOid);
+
+ui64 HexEncode(const char *src, size_t len, char *dst);
+} // NYql
+
diff --git a/yql/essentials/parser/pg_wrapper/interface/ya.make b/yql/essentials/parser/pg_wrapper/interface/ya.make
new file mode 100644
index 00000000000..92fe7ff1669
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/interface/ya.make
@@ -0,0 +1,27 @@
+LIBRARY()
+
+SRCS(
+ codec.h
+ compare.h
+ comp_factory.h
+ context.h
+ interface.h
+ interface.cpp
+ pack.h
+ parser.h
+ type_desc.h
+ utils.h
+)
+
+PEERDIR(
+ util
+ yql/essentials/ast
+ yql/essentials/public/udf
+ yql/essentials/public/udf/arrow
+ yql/essentials/core/cbo
+ library/cpp/disjoint_sets
+)
+
+YQL_LAST_ABI_VERSION()
+
+END()