From ee8ed85da3b0548eba96f2ec68fa7ba577bba586 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Mon, 13 Aug 2001 21:34:54 +0000
Subject: [PATCH] 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.
---
 doc/src/sgml/ref/create_function.sgml | 23 +++----
 doc/src/sgml/ref/create_language.sgml | 30 +++------
 doc/src/sgml/ref/drop_language.sgml   |  9 +--
 doc/src/sgml/xplang.sgml              | 16 +++--
 src/backend/parser/gram.y             | 20 +++---
 src/bin/scripts/createlang.sh         | 54 ++++++++--------
 src/bin/scripts/droplang              | 89 ++++++++++++++-------------
 7 files changed, 118 insertions(+), 123 deletions(-)

diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml
index 2a28925dff5..aa6552dca7d 100644
--- a/doc/src/sgml/ref/create_function.sgml
+++ b/doc/src/sgml/ref/create_function.sgml
@@ -1,5 +1,5 @@
 <!--
-$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:
diff --git a/doc/src/sgml/ref/create_language.sgml b/doc/src/sgml/ref/create_language.sgml
index f5e1c6ffa90..73dd7773e81 100644
--- a/doc/src/sgml/ref/create_language.sgml
+++ b/doc/src/sgml/ref/create_language.sgml
@@ -1,5 +1,5 @@
 <!--
-$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>
diff --git a/doc/src/sgml/ref/drop_language.sgml b/doc/src/sgml/ref/drop_language.sgml
index 4bfd95861df..45331c6ae1f 100644
--- a/doc/src/sgml/ref/drop_language.sgml
+++ b/doc/src/sgml/ref/drop_language.sgml
@@ -1,5 +1,5 @@
 <!--
-$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>
diff --git a/doc/src/sgml/xplang.sgml b/doc/src/sgml/xplang.sgml
index 46a59c6172f..6118836c545 100644
--- a/doc/src/sgml/xplang.sgml
+++ b/doc/src/sgml/xplang.sgml
@@ -1,5 +1,5 @@
 <!--
-$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
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c16bd865cef..391d821119a 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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;
diff --git a/src/bin/scripts/createlang.sh b/src/bin/scripts/createlang.sh
index 7c4b959367a..fe9cf5fb0ea 100644
--- a/src/bin/scripts/createlang.sh
+++ b/src/bin/scripts/createlang.sh
@@ -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
diff --git a/src/bin/scripts/droplang b/src/bin/scripts/droplang
index 82de3742d41..95d587cce0a 100644
--- a/src/bin/scripts/droplang
+++ b/src/bin/scripts/droplang
@@ -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
-- 
GitLab