diff --git a/doc/src/sgml/ref/createlang.sgml b/doc/src/sgml/ref/createlang.sgml index 36bd318e1de425802284db6a813b2d65da6380d2..0bc1976c15e1a270a85ea2e17bac51a8a11598dc 100644 --- a/doc/src/sgml/ref/createlang.sgml +++ b/doc/src/sgml/ref/createlang.sgml @@ -12,7 +12,7 @@ PostgreSQL documentation <refnamediv> <refname>createlang</refname> - <refpurpose>define a new <productname>PostgreSQL</productname> procedural language</refpurpose> + <refpurpose>install a <productname>PostgreSQL</productname> procedural language</refpurpose> </refnamediv> <indexterm zone="app-createlang"> @@ -40,12 +40,22 @@ PostgreSQL documentation <title>Description</title> <para> - <application>createlang</application> is a utility for adding a new - programming language to a <productname>PostgreSQL</productname> database. + <application>createlang</application> is a utility for adding a + procedural language to a <productname>PostgreSQL</productname> database. + </para> + + <para> <application>createlang</application> is just a wrapper around the - <xref linkend="sql-createlanguage"> - command. + <xref linkend="sql-createextension"> SQL command. </para> + + <caution> + <para> + <application>createlang</application> is deprecated and may be removed + in a future <productname>PostgreSQL</productname> release. Direct use + of the <command>CREATE EXTENSION</> command is recommended instead. + </para> + </caution> </refsect1> @@ -60,8 +70,7 @@ PostgreSQL documentation <term><replaceable class="parameter">langname</replaceable></term> <listitem> <para> - Specifies the name of the procedural programming language to be - defined. + Specifies the name of the procedural language to be installed. </para> </listitem> </varlistentry> @@ -273,6 +282,7 @@ PostgreSQL documentation <simplelist type="inline"> <member><xref linkend="app-droplang"></member> + <member><xref linkend="sql-createextension"></member> <member><xref linkend="sql-createlanguage"></member> </simplelist> </refsect1> diff --git a/doc/src/sgml/ref/droplang.sgml b/doc/src/sgml/ref/droplang.sgml index c9d034a4c14ac69b61b7ca44ce8b7a2eca07b81d..810c78e52154eb842561c008ab65b07000eab8a0 100644 --- a/doc/src/sgml/ref/droplang.sgml +++ b/doc/src/sgml/ref/droplang.sgml @@ -42,19 +42,22 @@ PostgreSQL documentation <para> <application>droplang</application> is a utility for removing an - existing programming language from a + existing procedural language from a <productname>PostgreSQL</productname> database. - <application>droplang</application> can drop any procedural language, - even those not supplied by the <productname>PostgreSQL</> distribution. </para> + <para> - Although backend programming languages can be removed directly using - several <acronym>SQL</acronym> commands, it is recommended to use - <application>droplang</application> because it performs a number - of checks and is much easier to use. See - <xref linkend="sql-droplanguage"> - for more. + <application>droplang</application> is just a wrapper around the + <xref linkend="sql-dropextension"> SQL command. </para> + + <caution> + <para> + <application>droplang</application> is deprecated and may be removed + in a future <productname>PostgreSQL</productname> release. Direct use + of the <command>DROP EXTENSION</> command is recommended instead. + </para> + </caution> </refsect1> @@ -69,7 +72,7 @@ PostgreSQL documentation <term><replaceable class="parameter">langname</replaceable></term> <listitem> <para> - Specifies the name of the backend programming language to be removed. + Specifies the name of the procedural language to be removed. </para> </listitem> </varlistentry> @@ -277,6 +280,7 @@ PostgreSQL documentation <simplelist type="inline"> <member><xref linkend="app-createlang"></member> + <member><xref linkend="sql-dropextension"></member> <member><xref linkend="sql-droplanguage"></member> </simplelist> </refsect1> diff --git a/src/bin/scripts/createlang.c b/src/bin/scripts/createlang.c index 3c68400528ab0cbc39ed6fcf2b73ee20c119dc69..c2153db630eec757c063385037417f0796f77530 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 0d03d3c4b717021dc9b6d1f7dcc9cefef564a9fb..83c1b531c7100c5e9bd8643be94593cb5eca6928 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 - */ - 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); /* - * Check that the handler function isn't used by some other 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(*) 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); + printfPQExpBuffer(&sql, "DROP EXTENSION \"%s\";\n", langname); - /* - * 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);