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.
This commit is contained in:
Tom Lane 2011-03-05 14:03:06 -05:00
parent c0f2b2e256
commit ba0c93a0f4
4 changed files with 47 additions and 175 deletions

View File

@ -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 just a wrapper around the
<xref linkend="sql-createlanguage">
command.
<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-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>

View File

@ -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>

View File

@ -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);

View File

@ -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);