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
|
|
@ -91,9 +91,44 @@ void operator<<(ProcKind &s, const Pgsql::Value &v)
|
|||
case 'w':
|
||||
s = ProcKind::Window;
|
||||
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(
|
||||
std::vector<Oid> argtypes,
|
||||
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()) {
|
||||
QString sql;
|
||||
|
||||
//wxString qtName = GetQuotedFullIdentifier() + wxT("(") + GetArgListWithNames(true) + wxT(")");
|
||||
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());
|
||||
|
||||
auto&& types = catalog().types();
|
||||
QString return_type = types->getByKey(rettype)->objectName();
|
||||
|
||||
|
||||
sql = QString("-- Function: %1\n\n"
|
||||
"-- DROP FUNCTION %1;\n\n"
|
||||
"CREATE OR REPLACE FUNCTION %2\n"
|
||||
" RETURNS %3 AS\n"
|
||||
).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 (isAggregate()) {
|
||||
/// \todo Support for aggregates
|
||||
createSqlCache = "-- aggregates not supported yet\n";
|
||||
return createSqlCache;
|
||||
}
|
||||
if (language == "c") {
|
||||
QString quoted_name = QString("%1(%2)").arg(fullyQualifiedQuotedObjectName(), argListWithNames(true));
|
||||
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();
|
||||
QString return_type = types->getByKey(rettype)->objectName();
|
||||
sql = QString("-- Function: %1\n\n"
|
||||
"-- DROP FUNCTION %1;\n\n"
|
||||
"CREATE OR REPLACE FUNCTION %2\n"
|
||||
" RETURNS %3"
|
||||
).arg(quoted_sig, quoted_name, return_type);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else {
|
||||
// | AS 'definition'
|
||||
sql += dollarQuoteString(src);
|
||||
}
|
||||
// sql += wxT("\n LANGUAGE ") + GetLanguage() + wxT(" ");
|
||||
sql += "\n LANGUAGE " % language % " ";
|
||||
// if (GetConnection()->BackendMinimumVersion(8, 4) && GetIsWindow())
|
||||
// sql += wxT("WINDOW ");
|
||||
|
||||
// { LANGUAGE lang_name
|
||||
sql += "\n LANGUAGE " % language->quotedObjectName();
|
||||
|
||||
/// \todo | TRANSFORM { FOR TYPE type_name } [, ... ]
|
||||
|
||||
// | WINDOW
|
||||
if (isWindow())
|
||||
sql += "WINDOW ";
|
||||
// sql += GetVolatility();
|
||||
sql += volatility();
|
||||
sql += " WINDOW";
|
||||
|
||||
if (!isProcedure()) {
|
||||
// F | IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF
|
||||
sql += " " % volatility();
|
||||
if (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)
|
||||
sql += " STRICT"
|
||||
;
|
||||
/// \todo F | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
|
||||
// if (GetSecureDefiner())
|
||||
// sql += wxT(" SECURITY DEFINER");
|
||||
// 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)
|
||||
sql += QString("n ROWS %1").arg(static_cast<double>(rows));
|
||||
|
||||
}
|
||||
|
||||
if (leakproof)
|
||||
sql += " LEAKPROOF";
|
||||
if (isstrict)
|
||||
sql += " STRICT";
|
||||
|
||||
// if (GetSecureDefiner())
|
||||
// sql += wxT(" SECURITY DEFINER");
|
||||
|
||||
sql += QString("\n COST %1").arg(cost);
|
||||
if (retset)
|
||||
sql += QString("n ROWS %1").arg(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 += wxT("\nALTER FUNCTION ") + qtSig
|
||||
// + wxT(" SET ") + configList.Item(i).BeforeFirst('=') + wxT("='") + configList.Item(i).AfterFirst('=') + wxT("';\n");
|
||||
// else
|
||||
// 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 }
|
||||
for (auto&& cfg : config) {
|
||||
auto before = cfg.section('=', 0, 0); // before first =
|
||||
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")
|
||||
// + GetOwnerSql(8, 0, wxT("FUNCTION ") + qtSig)
|
||||
// + GetGrant(wxT("X"), wxT("FUNCTION ") + qtSig);
|
||||
|
||||
sql += alterOwnerSql("FUNCTION " + quoted_sig);
|
||||
|
||||
// if (!GetComment().IsNull())
|
||||
// {
|
||||
// sql += wxT("COMMENT ON FUNCTION ") + qtSig
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue