Commit ee8ed85d authored by Peter Eisentraut's avatar Peter Eisentraut

Make LANCOMPILER clause in CREATE LANGUAGE optional. Allow "identifier"

syntax for language names (instead of 'string').

createlang now handles the case where a second language uses the same call
handler as an already installed language (e.g., plperl/plperlu).

droplang now handles the reverse case, i.e., dropping a language where
the call handler is still used by another language.  Moreover, droplang
can now be used to drop any user-defined language, not just the supplied
ones.
parent 38cfc958
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.24 2001/06/04 23:27:23 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.25 2001/08/13 21:34:51 petere Exp $
-->
<refentry id="SQL-CREATEFUNCTION">
......@@ -18,12 +18,12 @@ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.24 2001/06/04
CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">argtype</replaceable> [, ...] ] )
RETURNS <replaceable class="parameter">rettype</replaceable>
AS '<replaceable class="parameter">definition</replaceable>'
LANGUAGE '<replaceable class="parameter">langname</replaceable>'
LANGUAGE <replaceable class="parameter">langname</replaceable>
[ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ]
CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">argtype</replaceable> [, ...] ] )
RETURNS <replaceable class="parameter">rettype</replaceable>
AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
LANGUAGE '<replaceable class="parameter">langname</replaceable>'
LANGUAGE <replaceable class="parameter">langname</replaceable>
[ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ]
</synopsis>
</refsynopsisdiv>
......@@ -123,13 +123,14 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
<listitem>
<para>
May be '<literal>sql</literal>', '<literal>C</literal>',
'<literal>internal</literal>', or '<replaceable
class="parameter">plname</replaceable>', where '<replaceable
class="parameter">plname</replaceable>' is the name of a
May be <literal>SQL</literal>, <literal>C</literal>,
<literal>internal</literal>, or <replaceable
class="parameter">plname</replaceable>, where <replaceable
class="parameter">plname</replaceable> is the name of a
created procedural language. See
<xref linkend="sql-createlanguage">
for details.
for details. For backward compatibility, the name may be
enclosed by single quotes.
</para>
</listitem>
</varlistentry>
......@@ -261,7 +262,7 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
<programlisting>
CREATE FUNCTION one() RETURNS integer
AS 'SELECT 1 AS RESULT;'
LANGUAGE 'sql';
LANGUAGE SQL;
SELECT one() AS answer;
<computeroutput>
......@@ -281,7 +282,7 @@ SELECT one() AS answer;
<programlisting>
CREATE FUNCTION ean_checkdigit(char, char) RETURNS boolean
AS '/usr1/proj/bray/sql/funcs.so' LANGUAGE 'c';
AS '/usr1/proj/bray/sql/funcs.so' LANGUAGE C;
CREATE TABLE product (
id char(8) PRIMARY KEY,
......@@ -306,7 +307,7 @@ CREATE TABLE product (
<programlisting>
CREATE FUNCTION point(complex) RETURNS point
AS '/home/bernie/pgsql/lib/complex.so', 'complex_to_point'
LANGUAGE 'c';
LANGUAGE C;
</programlisting>
The C declaration of the function could be:
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.14 2000/11/20 20:36:46 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.15 2001/08/13 21:34:51 petere Exp $
Postgres documentation
-->
......@@ -23,9 +23,8 @@ Postgres documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE '<replaceable class="parameter">langname</replaceable>'
CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">langname</replaceable>
HANDLER <replaceable class="parameter">call_handler</replaceable>
LANCOMPILER '<replaceable class="parameter">comment</replaceable>'
</synopsis>
<refsect2 id="R2-SQL-CREATELANGUAGE-1">
......@@ -62,6 +61,10 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE '<replaceable class="parameter">langn
language cannot override one of the built-in languages of
<productname>Postgres</productname>.
</para>
<para>
For backward compatibility, the name may be enclosed by single
quotes.
</para>
</listitem>
</varlistentry>
......@@ -77,20 +80,6 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE '<replaceable class="parameter">langn
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">comment</replaceable></term>
<listitem>
<para>
The <function>LANCOMPILER</function> argument is the
string that will be
inserted in the <literal>LANCOMPILER</literal> attribute
of the new
<filename>pg_language</filename> entry. At present,
<productname>Postgres</productname> does not use
this attribute in any way.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
......@@ -346,10 +335,9 @@ plsample_call_handler(PG_FUNCTION_ARGS)
<programlisting>
CREATE FUNCTION plsample_call_handler () RETURNS opaque
AS '/usr/local/pgsql/lib/plsample.so'
LANGUAGE 'C';
CREATE PROCEDURAL LANGUAGE 'plsample'
HANDLER plsample_call_handler
LANCOMPILER 'PL/Sample';
LANGUAGE C;
CREATE LANGUAGE plsample
HANDLER plsample_call_handler;
</programlisting>
</para>
</refsect1>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_language.sgml,v 1.9 2000/12/25 23:15:26 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_language.sgml,v 1.10 2001/08/13 21:34:51 petere Exp $
Postgres documentation
-->
......@@ -23,7 +23,7 @@ Postgres documentation
<date>1999-07-20</date>
</refsynopsisdivinfo>
<synopsis>
DROP [ PROCEDURAL ] LANGUAGE '<replaceable class="PARAMETER">name</replaceable>'
DROP [ PROCEDURAL ] LANGUAGE <replaceable class="PARAMETER">name</replaceable>
</synopsis>
<refsect2 id="R2-SQL-DROPLANGUAGE-1">
......@@ -40,7 +40,8 @@ DROP [ PROCEDURAL ] LANGUAGE '<replaceable class="PARAMETER">name</replaceable>'
<term><replaceable class="PARAMETER">name</replaceable></term>
<listitem>
<para>
The name of an existing procedural language.
The name of an existing procedural language. For backward
compatibility, the name may be enclosed by single quotes.
</para>
</listitem>
</varlistentry>
......@@ -132,7 +133,7 @@ ERROR: Language "<replaceable class="parameter">name</replaceable>" doesn't exis
This command removes the PL/Sample language:
<programlisting>
DROP PROCEDURAL LANGUAGE 'plsample';
DROP LANGUAGE plsample;
</programlisting>
</para>
</refsect1>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/xplang.sgml,v 1.13 2001/05/19 09:01:10 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/xplang.sgml,v 1.14 2001/08/13 21:34:51 petere Exp $
-->
<chapter id="xplang">
......@@ -79,7 +79,7 @@ createlang plpgsql template1
<synopsis>
CREATE FUNCTION <replaceable>handler_function_name</replaceable> ()
RETURNS OPAQUE AS
'<replaceable>path-to-shared-object</replaceable>' LANGUAGE 'C';
'<replaceable>path-to-shared-object</replaceable>' LANGUAGE C;
</synopsis>
The special return type of <type>OPAQUE</type> tells
the database that this function does not return one of
......@@ -92,9 +92,8 @@ CREATE FUNCTION <replaceable>handler_function_name</replaceable> ()
<para>
The PL must be declared with the command
<synopsis>
CREATE <optional>TRUSTED</optional> <optional>PROCEDURAL</optional> LANGUAGE '<replaceable>language-name</replaceable>'
HANDLER <replaceable>handler_function_name</replaceable>
LANCOMPILER '<replaceable>description</replaceable>';
CREATE <optional>TRUSTED</optional> <optional>PROCEDURAL</optional> LANGUAGE <replaceable>language-name</replaceable>
HANDLER <replaceable>handler_function_name</replaceable>;
</synopsis>
The optional key word <token>TRUSTED</token> tells
whether ordinary database users that have no superuser
......@@ -130,7 +129,7 @@ CREATE <optional>TRUSTED</optional> <optional>PROCEDURAL</optional> LANGUAGE '<r
<programlisting>
CREATE FUNCTION plpgsql_call_handler () RETURNS OPAQUE AS
'$libdir/plpgsql' LANGUAGE 'C';
'$libdir/plpgsql' LANGUAGE C;
</programlisting>
</para>
</step>
......@@ -139,9 +138,8 @@ CREATE FUNCTION plpgsql_call_handler () RETURNS OPAQUE AS
<para>
The command
<programlisting>
CREATE TRUSTED PROCEDURAL LANGUAGE 'plpgsql'
HANDLER plpgsql_call_handler
LANCOMPILER 'PL/pgSQL';
CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql
HANDLER plpgsql_call_handler;
</programlisting>
then defines that the previously declared call handler function
should be invoked for functions and trigger procedures where the
......
......@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.243 2001/08/10 18:57:36 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.244 2001/08/13 21:34:51 petere Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
......@@ -163,7 +163,8 @@ static void doNegateFloat(Value *v);
%type <list> OptUserList
%type <defelt> OptUserElem
%type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted, opt_procedural
%type <boolean> TriggerActionTime, TriggerForSpec, opt_trusted, opt_procedural
%type <str> opt_lancompiler
%type <str> OptConstrFromTable
......@@ -1688,23 +1689,26 @@ IntegerOnly: Iconst
*
*****************************************************************************/
CreatePLangStmt: CREATE PLangTrusted opt_procedural LANGUAGE Sconst
HANDLER func_name LANCOMPILER Sconst
CreatePLangStmt: CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
HANDLER func_name opt_lancompiler
{
CreatePLangStmt *n = makeNode(CreatePLangStmt);
n->plname = $5;
n->plhandler = $7;
n->plcompiler = $9;
n->plcompiler = $8;
n->pltrusted = $2;
$$ = (Node *)n;
}
;
PLangTrusted: TRUSTED { $$ = TRUE; }
opt_trusted: TRUSTED { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
DropPLangStmt: DROP opt_procedural LANGUAGE Sconst
opt_lancompiler: LANCOMPILER Sconst { $$ = $2; }
| /*EMPTY*/ { $$ = ""; }
DropPLangStmt: DROP opt_procedural LANGUAGE ColId_or_Sconst
{
DropPLangStmt *n = makeNode(DropPLangStmt);
n->plname = $4;
......@@ -2511,7 +2515,7 @@ RecipeStmt: EXECUTE RECIPE recipe_name
*****************************************************************************/
ProcedureStmt: CREATE FUNCTION func_name func_args
RETURNS func_return AS func_as LANGUAGE Sconst opt_with
RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with
{
ProcedureStmt *n = makeNode(ProcedureStmt);
n->funcname = $3;
......
......@@ -7,7 +7,7 @@
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.28 2001/06/18 21:40:06 momjian Exp $
# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.29 2001/08/13 21:34:54 petere Exp $
#
#-------------------------------------------------------------------------
......@@ -121,7 +121,7 @@ do
shift
done
if [ "$usage" ]; then
if [ -n "$usage" ]; then
echo "$CMDNAME installs a procedural language into a PostgreSQL database."
echo
echo "Usage:"
......@@ -158,7 +158,7 @@ fi
# List option
# ----------
if [ "$list" ]; then
sqlcmd="SELECT lanname as \"Name\", lanpltrusted as \"Trusted?\", lancompiler as \"Compiler\" FROM pg_language WHERE lanispl = 't';"
sqlcmd="SELECT lanname as \"Name\", lanpltrusted as \"Trusted?\" FROM pg_language WHERE lanispl = TRUE;"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
......@@ -185,46 +185,43 @@ fi
# ----------
# Check if supported and set related values
# ----------
langname=`echo "$langname" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
case "$langname" in
plpgsql)
lancomp="PL/pgSQL"
trusted="TRUSTED "
handler="plpgsql_call_handler"
object="plpgsql"
;;
pltcl)
lancomp="PL/Tcl"
trusted="TRUSTED "
handler="pltcl_call_handler"
object="pltcl"
;;
pltclu)
lancomp="PL/Tcl (untrusted)"
trusted=""
handler="pltclu_call_handler"
object="pltcl"
;;
plperl)
lancomp="PL/Perl"
trusted="TRUSTED "
handler="plperl_call_handler"
object="plperl"
;;
plperlu)
lancomp="PL/Perl (untrusted)"
trusted=""
handler="plperl_call_handler"
object="plperl"
;;
plpython)
lancomp="PL/Python"
trusted="TRUSTED "
handler="plpython_call_handler"
object="plpython"
;;
*)
echo "$CMDNAME: unsupported language '$langname'" 1>&2
echo "Supported languages are 'plpgsql', 'pltcl', 'pltclu', 'plperl', and 'plpython'." 1>&2
echo "$CMDNAME: unsupported language \"$langname\"" 1>&2
echo "Supported languages are plpgsql, pltcl, pltclu, plperl, plperlu, and plpython." 1>&2
exit 1
;;
esac
......@@ -244,39 +241,42 @@ if [ $? -ne 0 ]; then
echo "$CMDNAME: external error" 1>&2
exit 1
fi
if [ "$res" ]; then
echo "$CMDNAME: '$langname' is already installed in database $dbname" 1>&2
if [ -n "$res" ]; then
echo "$CMDNAME: language \"$langname\" is already installed in database $dbname" 1>&2
# separate exit status for "already installed"
exit 2
fi
# ----------
# Check that there is no function named as the call handler
# Check whether the call handler exists
# ----------
sqlcmd="SELECT oid FROM pg_proc WHERE proname = '$handler';"
sqlcmd="SELECT oid FROM pg_proc WHERE proname = '$handler' AND prorettype = 0 AND pronargs = 0;"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
res=`$PSQL "$sqlcmd"`
if [ ! -z "$res" ]; then
echo "$CMDNAME: A function named '$handler' already exists. Installation aborted." 1>&2
exit 1
if [ -n "$res" ]; then
handlerexists=yes
else
handlerexists=no
fi
# ----------
# Create the call handler and the language
# ----------
sqlcmd="CREATE FUNCTION $handler () RETURNS OPAQUE AS '$PGLIB/${object}' LANGUAGE 'C';"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
$PSQL "$sqlcmd"
if [ $? -ne 0 ]; then
echo "$CMDNAME: language installation failed" 1>&2
exit 1
if [ "$handlerexists" = no ]; then
sqlcmd="CREATE FUNCTION \"$handler\" () RETURNS OPAQUE AS '$PGLIB/${object}' LANGUAGE C;"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
$PSQL "$sqlcmd"
if [ $? -ne 0 ]; then
echo "$CMDNAME: language installation failed" 1>&2
exit 1
fi
fi
sqlcmd="CREATE ${trusted}PROCEDURAL LANGUAGE '$langname' HANDLER $handler LANCOMPILER '$lancomp';"
sqlcmd="CREATE ${trusted}LANGUAGE \"$langname\" HANDLER \"$handler\";"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
......
......@@ -7,7 +7,7 @@
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/droplang,v 1.15 2001/05/12 01:30:30 petere Exp $
# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/droplang,v 1.16 2001/08/13 21:34:54 petere Exp $
#
#-------------------------------------------------------------------------
......@@ -130,7 +130,7 @@ fi
if [ "$list" ]; then
sqlcmd="SELECT lanname as \"Name\", lanpltrusted as \"Trusted?\", lancompiler as \"Compiler\" FROM pg_language WHERE lanispl = 't'"
sqlcmd="SELECT lanname as \"Name\", lanpltrusted as \"Trusted?\" FROM pg_language WHERE lanispl = TRUE"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
......@@ -157,55 +157,23 @@ if [ -z "$langname" ]; then
read langname
fi
# ----------
# Check if supported and set related values
# ----------
case "$langname" in
plpgsql)
lancomp="PL/pgSQL"
handler="plpgsql_call_handler"
;;
pltcl)
lancomp="PL/Tcl"
handler="pltcl_call_handler"
;;
pltclu)
lancomp="PL/Tcl (untrusted)"
handler="pltclu_call_handler"
;;
plperl)
lancomp="PL/Perl"
handler="plperl_call_handler"
;;
plpython)
lancomp="PL/Python"
handler="plpython_call_handler"
;;
*)
echo "$CMDNAME: unsupported language '$langname'" 1>&2
echo "Supported languages are 'plpgsql', 'pltcl', 'pltclu', 'plperl', and 'plpython'." 1>&2
exit 1
;;
esac
PSQL="${PATHNAME}psql -A -t -q $PSQLOPT -d $dbname -c"
# ----------
# Make sure the language is installed
# Make sure the language is installed and find the oid of the handler function
# ----------
sqlcmd="SELECT oid FROM pg_language WHERE lanname = '$langname';"
sqlcmd="SELECT lanplcallfoid FROM pg_language WHERE lanname = '$langname' AND lanispl;"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
res=`$PSQL "$sqlcmd"`
lanplcallfoid=`$PSQL "$sqlcmd"`
if [ $? -ne 0 ]; then
echo "$CMDNAME: external error" 1>&2
exit 1
fi
if [ -z "$res" ]; then
echo "$CMDNAME: '$langname' is not installed in database $dbname" 1>&2
if [ -z "$lanplcallfoid" ]; then
echo "$CMDNAME: language \"$langname\" is not installed in database $dbname" 1>&2
exit 1
fi
......@@ -224,14 +192,32 @@ if [ $? -ne 0 ]; then
fi
if [ "$res" -ne 0 ]; then
echo "$CMDNAME: There are $res functions/trigger procedures declared in language" 1>&2
echo "$lancomp. Language not removed." 1>&2
echo "$langname. Language not removed." 1>&2
exit 1
fi
# ----------
# Drop the language and the call handler function
# Check that the handler function isn't used by some other language
# ----------
sqlcmd="DROP PROCEDURAL LANGUAGE '$langname';"
sqlcmd="SELECT count(*) FROM pg_language WHERE lanplcallfoid = $lanplcallfoid AND lanname <> '$langname';"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
res=`$PSQL "$sqlcmd"`
if [ $? -ne 0 ]; then
echo "$CMDNAME: external error" 1>&2
exit 1
fi
if [ "$res" -eq 0 ]; then
keephandler=no
else
keephandler=yes
fi
# ----------
# Drop the language
# ----------
sqlcmd="DROP LANGUAGE \"$langname\";"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
......@@ -241,7 +227,24 @@ if [ $? -ne 0 ]; then
exit 1
fi
sqlcmd="DROP FUNCTION $handler();"
# ----------
# Drop the call handler
# ----------
if [ "$keephandler" = yes ]; then
exit 0
fi
sqlcmd="SELECT proname FROM pg_proc WHERE oid = $lanplcallfoid;"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
handler=`$PSQL "$sqlcmd"`
if [ $? -ne 0 ]; then
echo "$CMDNAME: external error" 1>&2
exit 1
fi
sqlcmd="DROP FUNCTION \"$handler\" ();"
if [ "$showsql" = yes ]; then
echo "$sqlcmd"
fi
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment