From 43f8117bbd9bdfc6782a34db7687903d31c96f39 Mon Sep 17 00:00:00 2001 From: eelke Date: Sun, 23 Dec 2018 08:48:45 +0100 Subject: [PATCH] pg11: pg_proc, type of function is stored differently from pg11 forward Followed the more structured approach of pg11 in combining the different types into a kind field when reading from older versions we migrate the old fields to the new field. Change in 11 is because of PROCEDURE support. However full PROCEDURE support will be its own change and is registered as issue #37 --- pglablib/catalog/PgProc.cpp | 20 ++++++++++++++++++- pglablib/catalog/PgProc.h | 19 ++++++++++++++++-- pglablib/catalog/PgProcContainer.cpp | 30 ++++++++++++++++++++++------ 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/pglablib/catalog/PgProc.cpp b/pglablib/catalog/PgProc.cpp index bf779d1..0dc0517 100644 --- a/pglablib/catalog/PgProc.cpp +++ b/pglablib/catalog/PgProc.cpp @@ -73,7 +73,25 @@ namespace { return res; } +} +void operator<<(ProcKind &s, const Pgsql::Value &v) +{ + const char *c = v.c_str(); + switch (*c) { + case 'f': + s = ProcKind::Function; + break; + case 'p': + s = ProcKind::Procedure; + break; + case 'a': + s = ProcKind::Aggregate; + break; + case 'w': + s = ProcKind::Window; + break; + } } void PgProc::setArgs( @@ -239,7 +257,7 @@ QString PgProc::createSql() const sql += "\n LANGUAGE " % language % " "; // if (GetConnection()->BackendMinimumVersion(8, 4) && GetIsWindow()) // sql += wxT("WINDOW "); - if (iswindow) + if (isWindow()) sql += "WINDOW "; // sql += GetVolatility(); sql += volatility(); diff --git a/pglablib/catalog/PgProc.h b/pglablib/catalog/PgProc.h index 6de4438..49d5083 100644 --- a/pglablib/catalog/PgProc.h +++ b/pglablib/catalog/PgProc.h @@ -25,6 +25,15 @@ public: }; +enum class ProcKind { + Function, // f Normal function + Procedure, // p stored procedure, new in 11 can use transactions executed with CALL + Aggregate, // a + Window // w +}; + +void operator<<(ProcKind &s, const Pgsql::Value &v); + class PgProc: public PgNamespaceObject, public PgOwnedObject { public: using PgNamespaceObject::PgNamespaceObject; @@ -38,8 +47,9 @@ public: float rows = 0.f; // float4 Oid variadic = InvalidOid; // oid QString transform; // regproc - bool isagg = false; // bool - bool iswindow = false; // bool +// bool isagg = false; // bool < 11 +// bool iswindow = false; // bool << 11 + ProcKind kind = ProcKind::Function; // >= 11 bool secdef = false; // bool bool leakproof = false; // bool bool isstrict = false; // bool @@ -77,6 +87,11 @@ public: QString volatility() const; + bool isFunction() const { return kind == ProcKind::Function; } + bool isProcedure() const { return kind == ProcKind::Procedure; } + bool isAggregate() const { return kind == ProcKind::Aggregate; } + bool isWindow() const { return kind == ProcKind::Window; } + // bool isTrigger() const // { // return typname == wxT("\"trigger\"") || typname == wxT("trigger") || typname == wxT("event_trigger") || typname == wxT("\"event_trigger\"")) diff --git a/pglablib/catalog/PgProcContainer.cpp b/pglablib/catalog/PgProcContainer.cpp index fa1cb99..b3ef874 100644 --- a/pglablib/catalog/PgProcContainer.cpp +++ b/pglablib/catalog/PgProcContainer.cpp @@ -9,16 +9,18 @@ std::string PgProcContainer::getLoadQuery() const { std::string column_list = "oid,proname,pronamespace,proowner,prolang,procost,prorows," - "provariadic,protransform,proisagg,proiswindow,prosecdef,proleakproof," + "provariadic,protransform,prosecdef,proleakproof," "proisstrict,proretset,provolatile,pronargs,pronargdefaults,prorettype," "proargtypes,proallargtypes,proargmodes,proargnames,proargdefaults," "prosrc,probin,proconfig,proacl"; - if (minimumVersion(90500)) { + if (minimumVersion(90500)) column_list += ",protrftypes"; - } - if (minimumVersion(90600)) { + if (minimumVersion(90600)) column_list += ",proparallel"; - } + if (minimumVersion(110000)) + column_list += ",prokind"; + else + column_list += ",proisagg,proiswindow"; return "SELECT " + column_list + " FROM pg_proc"; } @@ -31,10 +33,12 @@ PgProc PgProcContainer::loadElem(const Pgsql::Row &row) Oid namespace_oid = col.nextValue(); Oid owner_oid = col.nextValue(); + //ProcKind + PgProc v(m_catalog, oid, name, namespace_oid); v.setOwnerOid(m_catalog, owner_oid); col >> v.lang >> v.cost >> v.rows - >> v.variadic >> v.transform >> v.isagg >> v.iswindow >> v.secdef >> v.leakproof + >> v.variadic >> v.transform >> v.secdef >> v.leakproof >> v.isstrict >> v.retset >> v.provolatile >> v.nargs >> v.nargdefaults >> v.rettype; @@ -55,6 +59,20 @@ PgProc PgProcContainer::loadElem(const Pgsql::Row &row) if (minimumVersion(90600)) { col >> v.parallel; } + if (minimumVersion(110000)) + col >> v.kind; + else { + bool agg, window; + col >> agg >> window; + if (agg) + v.kind = ProcKind::Aggregate; + else if (window) + v.kind = ProcKind::Window; + else { + v.kind = ProcKind::Function; + } + // Only 11 and higher has ProcKind::Procedure! + } return v; }