mirror of
https://github.com/postgres/postgres.git
synced 2025-07-15 19:21:59 +03:00
Implement the DO statement to support execution of PL code without having
to create a function for it. Procedural languages now have an additional entry point, namely a function to execute an inline code block. This seemed a better design than trying to hide the transient-ness of the code from the PL. As of this patch, only plpgsql has an inline handler, but probably people will soon write handlers for the other standard PLs. In passing, remove the long-dead LANCOMPILER option of CREATE LANGUAGE. Petr Jelinek
This commit is contained in:
@ -5,7 +5,7 @@
|
||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/bin/scripts/droplang.c,v 1.31 2009/02/26 16:02:39 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/scripts/droplang.c,v 1.32 2009/09/22 23:43:41 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -38,7 +38,6 @@ main(int argc, char *argv[])
|
||||
const char *progname;
|
||||
int optindex;
|
||||
int c;
|
||||
|
||||
bool listlangs = false;
|
||||
const char *dbname = NULL;
|
||||
char *host = NULL;
|
||||
@ -47,19 +46,20 @@ main(int argc, char *argv[])
|
||||
enum trivalue prompt_password = TRI_DEFAULT;
|
||||
bool echo = false;
|
||||
char *langname = NULL;
|
||||
|
||||
char *p;
|
||||
Oid lanplcallfoid;
|
||||
Oid laninline;
|
||||
Oid lanvalidator;
|
||||
char *handler;
|
||||
char *inline_handler;
|
||||
char *validator;
|
||||
char *handler_ns;
|
||||
char *inline_ns;
|
||||
char *validator_ns;
|
||||
bool keephandler;
|
||||
bool keepinline;
|
||||
bool keepvalidator;
|
||||
|
||||
PQExpBufferData sql;
|
||||
|
||||
PGconn *conn;
|
||||
PGresult *result;
|
||||
|
||||
@ -190,10 +190,10 @@ main(int argc, char *argv[])
|
||||
executeCommand(conn, "SET search_path = pg_catalog;", progname, echo);
|
||||
|
||||
/*
|
||||
* Make sure the language is installed and find the OIDs of the handler
|
||||
* and validator functions
|
||||
* Make sure the language is installed and find the OIDs of the
|
||||
* language support functions
|
||||
*/
|
||||
printfPQExpBuffer(&sql, "SELECT lanplcallfoid, lanvalidator "
|
||||
printfPQExpBuffer(&sql, "SELECT lanplcallfoid, laninline, lanvalidator "
|
||||
"FROM pg_language WHERE lanname = '%s' AND lanispl;",
|
||||
langname);
|
||||
result = executeQuery(conn, sql.data, progname, echo);
|
||||
@ -206,7 +206,8 @@ main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
lanplcallfoid = atooid(PQgetvalue(result, 0, 0));
|
||||
lanvalidator = atooid(PQgetvalue(result, 0, 1));
|
||||
laninline = atooid(PQgetvalue(result, 0, 1));
|
||||
lanvalidator = atooid(PQgetvalue(result, 0, 2));
|
||||
PQclear(result);
|
||||
|
||||
/*
|
||||
@ -260,6 +261,44 @@ main(int argc, char *argv[])
|
||||
handler_ns = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the inline function isn't used by some other language
|
||||
*/
|
||||
if (OidIsValid(laninline))
|
||||
{
|
||||
printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language "
|
||||
"WHERE laninline = %u AND lanname <> '%s';",
|
||||
laninline, langname);
|
||||
result = executeQuery(conn, sql.data, progname, echo);
|
||||
if (strcmp(PQgetvalue(result, 0, 0), "0") == 0)
|
||||
keepinline = false;
|
||||
else
|
||||
keepinline = true;
|
||||
PQclear(result);
|
||||
}
|
||||
else
|
||||
keepinline = true; /* don't try to delete it */
|
||||
|
||||
/*
|
||||
* Find the inline handler name
|
||||
*/
|
||||
if (!keepinline)
|
||||
{
|
||||
printfPQExpBuffer(&sql, "SELECT proname, (SELECT nspname "
|
||||
"FROM pg_namespace ns WHERE ns.oid = pronamespace) "
|
||||
"AS prons FROM pg_proc WHERE oid = %u;",
|
||||
laninline);
|
||||
result = executeQuery(conn, sql.data, progname, echo);
|
||||
inline_handler = strdup(PQgetvalue(result, 0, 0));
|
||||
inline_ns = strdup(PQgetvalue(result, 0, 1));
|
||||
PQclear(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
inline_handler = NULL;
|
||||
inline_ns = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the validator function isn't used by some other language
|
||||
*/
|
||||
@ -305,6 +344,9 @@ main(int argc, char *argv[])
|
||||
if (!keephandler)
|
||||
appendPQExpBuffer(&sql, "DROP FUNCTION \"%s\".\"%s\" ();\n",
|
||||
handler_ns, handler);
|
||||
if (!keepinline)
|
||||
appendPQExpBuffer(&sql, "DROP FUNCTION \"%s\".\"%s\" (internal);\n",
|
||||
inline_ns, inline_handler);
|
||||
if (!keepvalidator)
|
||||
appendPQExpBuffer(&sql, "DROP FUNCTION \"%s\".\"%s\" (oid);\n",
|
||||
validator_ns, validator);
|
||||
|
Reference in New Issue
Block a user