From ba0c93a0f46ca70cae47a8817067c1e98482979f Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 5 Mar 2011 14:03:06 -0500 Subject: [PATCH] Convert createlang/droplang to use CREATE/DROP EXTENSION. In createlang this is a one-line change. In droplang there's a whole lot of cruft that can be discarded since the extension mechanism now manages removal of the language's support functions. Also, add deprecation notices to these two programs' reference pages, since per discussion we may toss them overboard altogether in a release or two. --- doc/src/sgml/ref/createlang.sgml | 26 +++-- doc/src/sgml/ref/droplang.sgml | 24 +++-- src/bin/scripts/createlang.c | 10 +- src/bin/scripts/droplang.c | 162 ++----------------------------- 4 files changed, 47 insertions(+), 175 deletions(-) diff --git a/doc/src/sgml/ref/createlang.sgml b/doc/src/sgml/ref/createlang.sgml index 36bd318e1d..0bc1976c15 100644 --- a/doc/src/sgml/ref/createlang.sgml +++ b/doc/src/sgml/ref/createlang.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation createlang - define a new PostgreSQL procedural language + install a PostgreSQL procedural language @@ -40,12 +40,22 @@ PostgreSQL documentation Description - createlang is a utility for adding a new - programming language to a PostgreSQL database. - createlang is just a wrapper around the - - command. + createlang is a utility for adding a + procedural language to a PostgreSQL database. + + + createlang is just a wrapper around the + SQL command. + + + + + createlang is deprecated and may be removed + in a future PostgreSQL release. Direct use + of the CREATE EXTENSION command is recommended instead. + + @@ -60,8 +70,7 @@ PostgreSQL documentation langname - Specifies the name of the procedural programming language to be - defined. + Specifies the name of the procedural language to be installed. @@ -273,6 +282,7 @@ PostgreSQL documentation + diff --git a/doc/src/sgml/ref/droplang.sgml b/doc/src/sgml/ref/droplang.sgml index c9d034a4c1..810c78e521 100644 --- a/doc/src/sgml/ref/droplang.sgml +++ b/doc/src/sgml/ref/droplang.sgml @@ -42,19 +42,22 @@ PostgreSQL documentation droplang is a utility for removing an - existing programming language from a + existing procedural language from a PostgreSQL database. - droplang can drop any procedural language, - even those not supplied by the PostgreSQL distribution. + - Although backend programming languages can be removed directly using - several SQL commands, it is recommended to use - droplang because it performs a number - of checks and is much easier to use. See - - for more. + droplang is just a wrapper around the + SQL command. + + + + droplang is deprecated and may be removed + in a future PostgreSQL release. Direct use + of the DROP EXTENSION command is recommended instead. + + @@ -69,7 +72,7 @@ PostgreSQL documentation langname - Specifies the name of the backend programming language to be removed. + Specifies the name of the procedural language to be removed. @@ -277,6 +280,7 @@ PostgreSQL documentation + diff --git a/src/bin/scripts/createlang.c b/src/bin/scripts/createlang.c index 3c68400528..c2153db630 100644 --- a/src/bin/scripts/createlang.c +++ b/src/bin/scripts/createlang.c @@ -188,7 +188,15 @@ main(int argc, char *argv[]) } PQclear(result); - printfPQExpBuffer(&sql, "CREATE LANGUAGE \"%s\";\n", langname); + /* + * In 9.1 and up, assume that languages should be installed using CREATE + * EXTENSION. However, it's possible this tool could be used against an + * older server, and it's easy enough to continue supporting the old way. + */ + if (PQserverVersion(conn) >= 90100) + printfPQExpBuffer(&sql, "CREATE EXTENSION \"%s\";\n", langname); + else + printfPQExpBuffer(&sql, "CREATE LANGUAGE \"%s\";\n", langname); if (echo) printf("%s", sql.data); diff --git a/src/bin/scripts/droplang.c b/src/bin/scripts/droplang.c index 0d03d3c4b7..83c1b531c7 100644 --- a/src/bin/scripts/droplang.c +++ b/src/bin/scripts/droplang.c @@ -9,8 +9,8 @@ * *------------------------------------------------------------------------- */ - #include "postgres_fe.h" + #include "common.h" #include "print.h" @@ -47,18 +47,6 @@ main(int argc, char *argv[]) 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 +178,9 @@ 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 language - * support functions + * Make sure the language is installed */ - printfPQExpBuffer(&sql, "SELECT lanplcallfoid, laninline, lanvalidator " + printfPQExpBuffer(&sql, "SELECT oid " "FROM pg_language WHERE lanname = '%s' AND lanispl;", langname); result = executeQuery(conn, sql.data, progname, echo); @@ -205,151 +192,14 @@ main(int argc, char *argv[]) progname, langname, dbname); exit(1); } - lanplcallfoid = atooid(PQgetvalue(result, 0, 0)); - laninline = atooid(PQgetvalue(result, 0, 1)); - lanvalidator = atooid(PQgetvalue(result, 0, 2)); PQclear(result); /* - * Check that there are no functions left defined in that language + * Attempt to drop the language. We do not use CASCADE, so that + * the drop will fail if there are any functions in the language. */ - printfPQExpBuffer(&sql, "SELECT count(proname) FROM pg_proc P, " - "pg_language L WHERE P.prolang = L.oid " - "AND L.lanname = '%s';", langname); - result = executeQuery(conn, sql.data, progname, echo); - if (strcmp(PQgetvalue(result, 0, 0), "0") != 0) - { - PQfinish(conn); - fprintf(stderr, - _("%s: still %s functions declared in language \"%s\"; " - "language not removed\n"), - progname, PQgetvalue(result, 0, 0), langname); - exit(1); - } - PQclear(result); + printfPQExpBuffer(&sql, "DROP EXTENSION \"%s\";\n", langname); - /* - * Check that the handler function isn't used by some other language - */ - printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language " - "WHERE lanplcallfoid = %u AND lanname <> '%s';", - lanplcallfoid, langname); - result = executeQuery(conn, sql.data, progname, echo); - if (strcmp(PQgetvalue(result, 0, 0), "0") == 0) - keephandler = false; - else - keephandler = true; - PQclear(result); - - /* - * Find the handler name - */ - if (!keephandler) - { - printfPQExpBuffer(&sql, "SELECT proname, (SELECT nspname " - "FROM pg_namespace ns WHERE ns.oid = pronamespace) " - "AS prons FROM pg_proc WHERE oid = %u;", - lanplcallfoid); - result = executeQuery(conn, sql.data, progname, echo); - handler = strdup(PQgetvalue(result, 0, 0)); - handler_ns = strdup(PQgetvalue(result, 0, 1)); - PQclear(result); - } - else - { - handler = NULL; - 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 - */ - if (OidIsValid(lanvalidator)) - { - printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language " - "WHERE lanvalidator = %u AND lanname <> '%s';", - lanvalidator, langname); - result = executeQuery(conn, sql.data, progname, echo); - if (strcmp(PQgetvalue(result, 0, 0), "0") == 0) - keepvalidator = false; - else - keepvalidator = true; - PQclear(result); - } - else - keepvalidator = true; /* don't try to delete it */ - - /* - * Find the validator name - */ - if (!keepvalidator) - { - printfPQExpBuffer(&sql, "SELECT proname, (SELECT nspname " - "FROM pg_namespace ns WHERE ns.oid = pronamespace) " - "AS prons FROM pg_proc WHERE oid = %u;", - lanvalidator); - result = executeQuery(conn, sql.data, progname, echo); - validator = strdup(PQgetvalue(result, 0, 0)); - validator_ns = strdup(PQgetvalue(result, 0, 1)); - PQclear(result); - } - else - { - validator = NULL; - validator_ns = NULL; - } - - /* - * Drop the language and the functions - */ - printfPQExpBuffer(&sql, "DROP LANGUAGE \"%s\";\n", langname); - 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); if (echo) printf("%s", sql.data); result = PQexec(conn, sql.data);