Improved code generation for functions and procedures.
alter statements for configuration settings alter statement for owner
This commit is contained in:
parent
fc58acb252
commit
54d4dfface
5 changed files with 145 additions and 69 deletions
|
|
@ -30,7 +30,4 @@ const PgDatabaseCatalog& PgObject::catalog() const
|
||||||
return *m_catalog;
|
return *m_catalog;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test(PgObject a, PgObject b)
|
|
||||||
{
|
|
||||||
a = b;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include "PgAuthId.h"
|
#include "PgAuthId.h"
|
||||||
#include "PgAuthIdContainer.h"
|
#include "PgAuthIdContainer.h"
|
||||||
#include "PgDatabaseCatalog.h"
|
#include "PgDatabaseCatalog.h"
|
||||||
|
#include "SqlFormattingUtils.h"
|
||||||
|
|
||||||
void PgOwnedObject::setOwnerOid(PgDatabaseCatalog& cat, Oid oid)
|
void PgOwnedObject::setOwnerOid(PgDatabaseCatalog& cat, Oid oid)
|
||||||
{
|
{
|
||||||
|
|
@ -23,3 +24,9 @@ const PgAuthId* PgOwnedObject::owner() const
|
||||||
{
|
{
|
||||||
return m_owner;
|
return m_owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString PgOwnedObject::alterOwnerSql(const QString& ident) const
|
||||||
|
{
|
||||||
|
return QString("\nALTER %1 OWNER TO %2;").arg(ident, quoteIdent(ownerName()));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ public:
|
||||||
Oid ownerOid() const;
|
Oid ownerOid() const;
|
||||||
QString ownerName() const;
|
QString ownerName() const;
|
||||||
const PgAuthId* owner() const;
|
const PgAuthId* owner() const;
|
||||||
|
|
||||||
|
QString alterOwnerSql(const QString& ident) const;
|
||||||
private:
|
private:
|
||||||
Oid m_ownerOid = InvalidOid;
|
Oid m_ownerOid = InvalidOid;
|
||||||
const PgAuthId * m_owner;
|
const PgAuthId * m_owner;
|
||||||
|
|
|
||||||
|
|
@ -91,9 +91,44 @@ void operator<<(ProcKind &s, const Pgsql::Value &v)
|
||||||
case 'w':
|
case 'w':
|
||||||
s = ProcKind::Window;
|
s = ProcKind::Window;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unexpected value for ProcKind");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void operator<<(ParallelMode &s, const Pgsql::Value &v)
|
||||||
|
{
|
||||||
|
const char *c = v.c_str();
|
||||||
|
switch (*c) {
|
||||||
|
case 'u':
|
||||||
|
s = ParallelMode::Unsafe;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
s = ParallelMode::Restricted;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
s = ParallelMode::Safe;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unexpected value for ParallelMode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString parallelModeToSql(ParallelMode pm, bool explicit_unsafe)
|
||||||
|
{
|
||||||
|
switch (pm) {
|
||||||
|
case ParallelMode::Unsafe:
|
||||||
|
return explicit_unsafe ? "PARALLEL UNSAFE" : "";
|
||||||
|
case ParallelMode::Restricted:
|
||||||
|
return "PARALLEL RESTRICTED";
|
||||||
|
case ParallelMode::Safe:
|
||||||
|
return "PARALLEL SAFE";
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unexpected value for pm in parallelModeToSql");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PgProc::setArgs(
|
void PgProc::setArgs(
|
||||||
std::vector<Oid> argtypes,
|
std::vector<Oid> argtypes,
|
||||||
std::vector<Oid> allargtypes,
|
std::vector<Oid> allargtypes,
|
||||||
|
|
@ -210,89 +245,106 @@ QString PgProc::argSigList(const bool forScript) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QString PgProc::createSql() const
|
const QString& PgProc::createSql() const
|
||||||
{
|
{
|
||||||
if (createSqlCache.isEmpty()) {
|
if (createSqlCache.isEmpty()) {
|
||||||
QString sql;
|
QString sql;
|
||||||
|
|
||||||
//wxString qtName = GetQuotedFullIdentifier() + wxT("(") + GetArgListWithNames(true) + wxT(")");
|
if (isAggregate()) {
|
||||||
|
/// \todo Support for aggregates
|
||||||
|
createSqlCache = "-- aggregates not supported yet\n";
|
||||||
|
return createSqlCache;
|
||||||
|
}
|
||||||
QString quoted_name = QString("%1(%2)").arg(fullyQualifiedQuotedObjectName(), argListWithNames(true));
|
QString quoted_name = QString("%1(%2)").arg(fullyQualifiedQuotedObjectName(), argListWithNames(true));
|
||||||
// wxString qtSig = GetQuotedFullIdentifier() + wxT("(") + GetArgSigList() + wxT(")");
|
|
||||||
QString quoted_sig = QString("%1(%2)").arg(fullyQualifiedQuotedObjectName(), argSigList());
|
QString quoted_sig = QString("%1(%2)").arg(fullyQualifiedQuotedObjectName(), argSigList());
|
||||||
|
if (isProcedure()) {
|
||||||
|
// P CREATE [ OR REPLACE ] PROCEDURE
|
||||||
|
// name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
|
||||||
|
sql = QString("-- Procedure: %1\n\n"
|
||||||
|
"-- DROP PROCEDURE %1;\n\n"
|
||||||
|
"CREATE OR REPLACE PROCEDURE %2\n"
|
||||||
|
).arg(quoted_sig, quoted_name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// all other kinds are functions
|
||||||
|
// F CREATE [ OR REPLACE ] FUNCTION
|
||||||
|
// name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
|
||||||
|
// F [ RETURNS rettype
|
||||||
|
/// \todo F | RETURNS TABLE ( column_name column_type [, ...] ) ]
|
||||||
auto&& types = catalog().types();
|
auto&& types = catalog().types();
|
||||||
QString return_type = types->getByKey(rettype)->objectName();
|
QString return_type = types->getByKey(rettype)->objectName();
|
||||||
|
|
||||||
|
|
||||||
sql = QString("-- Function: %1\n\n"
|
sql = QString("-- Function: %1\n\n"
|
||||||
"-- DROP FUNCTION %1;\n\n"
|
"-- DROP FUNCTION %1;\n\n"
|
||||||
"CREATE OR REPLACE FUNCTION %2\n"
|
"CREATE OR REPLACE FUNCTION %2\n"
|
||||||
" RETURNS %3 AS\n"
|
" RETURNS %3"
|
||||||
).arg(quoted_sig, quoted_name, return_type);
|
).arg(quoted_sig, quoted_name, return_type);
|
||||||
|
|
||||||
// if (GetLanguage().IsSameAs(wxT("C"), false))
|
|
||||||
// {
|
|
||||||
// sql += qtDbString(GetBin()) + wxT(", ") + qtDbString(GetSource());
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// if (GetConnection()->BackendMinimumVersion(7, 5))
|
|
||||||
// sql += qtDbStringDollar(GetSource());
|
|
||||||
// else
|
|
||||||
// sql += qtDbString(GetSource());
|
|
||||||
// }
|
|
||||||
QString language;
|
|
||||||
{
|
|
||||||
auto l = catalog().languages()->getByKey(lang);
|
|
||||||
if (l)
|
|
||||||
language = l->objectName();
|
|
||||||
}
|
}
|
||||||
if (language == "c") {
|
|
||||||
|
sql += " AS\n";
|
||||||
|
auto language = catalog().languages()->getByKey(lang);
|
||||||
|
BOOST_ASSERT(language != nullptr);
|
||||||
|
|
||||||
|
if (language->isC()) {
|
||||||
|
// | AS 'obj_file', 'link_symbol'
|
||||||
sql += escapeLiteral(bin) % ", " % escapeLiteral(src);
|
sql += escapeLiteral(bin) % ", " % escapeLiteral(src);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// | AS 'definition'
|
||||||
sql += dollarQuoteString(src);
|
sql += dollarQuoteString(src);
|
||||||
}
|
}
|
||||||
// sql += wxT("\n LANGUAGE ") + GetLanguage() + wxT(" ");
|
|
||||||
sql += "\n LANGUAGE " % language % " ";
|
|
||||||
// if (GetConnection()->BackendMinimumVersion(8, 4) && GetIsWindow())
|
|
||||||
// sql += wxT("WINDOW ");
|
|
||||||
if (isWindow())
|
|
||||||
sql += "WINDOW ";
|
|
||||||
// sql += GetVolatility();
|
|
||||||
sql += volatility();
|
|
||||||
|
|
||||||
|
// { LANGUAGE lang_name
|
||||||
|
sql += "\n LANGUAGE " % language->quotedObjectName();
|
||||||
|
|
||||||
|
/// \todo | TRANSFORM { FOR TYPE type_name } [, ... ]
|
||||||
|
|
||||||
|
// | WINDOW
|
||||||
|
if (isWindow())
|
||||||
|
sql += " WINDOW";
|
||||||
|
|
||||||
|
if (!isProcedure()) {
|
||||||
|
// F | IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF
|
||||||
|
sql += " " % volatility();
|
||||||
if (leakproof)
|
if (leakproof)
|
||||||
sql += " LEAKPROOF";
|
sql += " LEAKPROOF";
|
||||||
|
// F | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
|
||||||
|
// CALLED ON NULL INPUT is the default so we never specify this
|
||||||
|
// RETURNS NULL ON NULL INPUT is an alias for STRICT so we use STRICT
|
||||||
if (isstrict)
|
if (isstrict)
|
||||||
sql += " STRICT";
|
sql += " STRICT"
|
||||||
|
;
|
||||||
// if (GetSecureDefiner())
|
/// \todo F | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
|
||||||
// sql += wxT(" SECURITY DEFINER");
|
// if (GetSecureDefiner())
|
||||||
|
// sql += wxT(" SECURITY DEFINER");
|
||||||
sql += QString("\n COST %1").arg(cost);
|
// F | PARALLEL { UNSAFE | RESTRICTED | SAFE }
|
||||||
|
sql += " " % parallelModeToSql(parallel);
|
||||||
|
// F | COST execution_cost
|
||||||
|
sql += QString("\n COST %1").arg(static_cast<double>(cost));
|
||||||
|
// F | ROWS result_rows
|
||||||
if (retset)
|
if (retset)
|
||||||
sql += QString("n ROWS %1").arg(rows);
|
sql += QString("n ROWS %1").arg(static_cast<double>(rows));
|
||||||
sql += ";";
|
|
||||||
// if (!sql.Strip(wxString::both).EndsWith(wxT(";")))
|
|
||||||
// sql += wxT(";");
|
|
||||||
|
|
||||||
// size_t i;
|
}
|
||||||
// for (i = 0 ; i < configList.GetCount() ; i++)
|
|
||||||
// {
|
|
||||||
// if (configList.Item(i).BeforeFirst('=') != wxT("search_path") &&
|
|
||||||
// configList.Item(i).BeforeFirst('=') != wxT("temp_tablespaces"))
|
sql += ";";
|
||||||
// sql += wxT("\nALTER FUNCTION ") + qtSig
|
|
||||||
// + wxT(" SET ") + configList.Item(i).BeforeFirst('=') + wxT("='") + configList.Item(i).AfterFirst('=') + wxT("';\n");
|
// | SET configuration_parameter { TO value | = value | FROM CURRENT }
|
||||||
// else
|
for (auto&& cfg : config) {
|
||||||
// sql += wxT("\nALTER FUNCTION ") + qtSig
|
auto before = cfg.section('=', 0, 0); // before first =
|
||||||
// + wxT(" SET ") + configList.Item(i).BeforeFirst('=') + wxT("=") + configList.Item(i).AfterFirst('=') + wxT(";\n");
|
auto after = cfg.section('=', 1, -1); // everything after first =
|
||||||
// }
|
if (before != "search_path" && before != "temp_tablespaces")
|
||||||
|
sql += QString("\nALTER FUNCTION %1 SET %2 TO '%3'").arg(quoted_sig, before, after);
|
||||||
|
else
|
||||||
|
sql += QString("\nALTER FUNCTION %1 SET %2 TO %3").arg(quoted_sig, before, after);
|
||||||
|
}
|
||||||
|
|
||||||
// sql += wxT("\n")
|
// sql += wxT("\n")
|
||||||
// + GetOwnerSql(8, 0, wxT("FUNCTION ") + qtSig)
|
|
||||||
// + GetGrant(wxT("X"), wxT("FUNCTION ") + qtSig);
|
// + GetGrant(wxT("X"), wxT("FUNCTION ") + qtSig);
|
||||||
|
|
||||||
|
sql += alterOwnerSql("FUNCTION " + quoted_sig);
|
||||||
|
|
||||||
// if (!GetComment().IsNull())
|
// if (!GetComment().IsNull())
|
||||||
// {
|
// {
|
||||||
// sql += wxT("COMMENT ON FUNCTION ") + qtSig
|
// sql += wxT("COMMENT ON FUNCTION ") + qtSig
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,24 @@ enum class ProcKind {
|
||||||
|
|
||||||
void operator<<(ProcKind &s, const Pgsql::Value &v);
|
void operator<<(ProcKind &s, const Pgsql::Value &v);
|
||||||
|
|
||||||
|
enum class ParallelMode {
|
||||||
|
Unsafe, // u, default
|
||||||
|
Restricted, // r,
|
||||||
|
Safe // s
|
||||||
|
};
|
||||||
|
|
||||||
|
void operator<<(ParallelMode &s, const Pgsql::Value &v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief parallelModeToSql
|
||||||
|
* @param pm The parallel mode
|
||||||
|
* @param explicit_unsafe When false an empty string is return for unsage when true
|
||||||
|
* a "PARALLEL UNSAFE" is returned.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
QString parallelModeToSql(ParallelMode pm, bool explicit_unsafe = false);
|
||||||
|
|
||||||
|
|
||||||
class PgProc: public PgNamespaceObject, public PgOwnedObject {
|
class PgProc: public PgNamespaceObject, public PgOwnedObject {
|
||||||
public:
|
public:
|
||||||
using PgNamespaceObject::PgNamespaceObject;
|
using PgNamespaceObject::PgNamespaceObject;
|
||||||
|
|
@ -55,7 +73,7 @@ public:
|
||||||
bool isstrict = false; // bool
|
bool isstrict = false; // bool
|
||||||
bool retset = false; // bool
|
bool retset = false; // bool
|
||||||
char provolatile = '\0'; // char
|
char provolatile = '\0'; // char
|
||||||
char parallel = '\0'; // char, version >= 9.6
|
ParallelMode parallel = ParallelMode::Unsafe; // char, version >= 9.6
|
||||||
int16_t nargs = 0; // int2
|
int16_t nargs = 0; // int2
|
||||||
int16_t nargdefaults; // = 0; // int2
|
int16_t nargdefaults; // = 0; // int2
|
||||||
Oid rettype = InvalidOid; // oid
|
Oid rettype = InvalidOid; // oid
|
||||||
|
|
@ -81,7 +99,7 @@ public:
|
||||||
// bool operator<(Oid _oid) const { return oid < _oid; }
|
// bool operator<(Oid _oid) const { return oid < _oid; }
|
||||||
// bool operator<(const PgProc &rhs) const { return oid < rhs.oid; }
|
// bool operator<(const PgProc &rhs) const { return oid < rhs.oid; }
|
||||||
|
|
||||||
QString createSql() const;
|
const QString& createSql() const;
|
||||||
QString argListWithNames(bool multiline = false) const;
|
QString argListWithNames(bool multiline = false) const;
|
||||||
QString argSigList(const bool forScript = false) const;
|
QString argSigList(const bool forScript = false) const;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue