From 581992ed36da490f52d5eb31b7cd0e2303233318 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathandbossart@gmail.com>
Date: Tue, 17 May 2022 13:28:17 -0700
Subject: [PATCH v1 2/3] Allow building only trusted or untrusted PL/Perl.

Presently, when the --with-perl configuration option is used, both
trusted and untrusted PL/Perl are built.  However, some users may
only want to build one or the other.  This change introduces an
optional argument that can be used to do so.  If
--with-perl='trusted' is specified, only trusted PL/Perl is built.
If --with-perl='untrusted' is specified, only untrusted PL/Perl is
built.  If --with-perl is given without an argument, both trusted
and untrusted PL/Perl are built.
---
 configure                               | 47 ++++++++++++++++++++++---
 configure.ac                            | 32 ++++++++++++++++-
 contrib/bool_plperl/Makefile            | 24 ++++++++++---
 contrib/hstore_plperl/Makefile          | 24 ++++++++++---
 contrib/jsonb_plperl/Makefile           | 24 ++++++++++---
 doc/src/sgml/installation.sgml          | 23 +++++++++++-
 src/Makefile.global.in                  |  2 ++
 src/include/pg_config.h.in              |  6 ++++
 src/pl/plperl/GNUmakefile               | 37 +++++++++++++------
 src/pl/plperl/expected/plperl_setup.out | 15 +++-----
 src/pl/plperl/expected/plperlu.out      | 27 ++++++++++++++
 src/pl/plperl/plperl.c                  | 10 ++++++
 src/pl/plperl/sql/plperl_setup.sql      | 11 +++---
 src/pl/plperl/sql/plperlu.sql           | 29 +++++++++++++++
 14 files changed, 265 insertions(+), 46 deletions(-)

diff --git a/configure b/configure
index 7dec6b7bf9..faa8b1a2e3 100755
--- a/configure
+++ b/configure
@@ -723,6 +723,8 @@ with_krb_srvnam
 krb_srvtab
 with_gssapi
 with_python
+PERL_UNTRUSTED
+PERL_TRUSTED
 with_perl
 with_tcl
 ICU_LIBS
@@ -1563,7 +1565,8 @@ Optional Packages:
   --with-icu              build with ICU support
   --with-tcl              build Tcl modules (PL/Tcl)
   --with-tclconfig=DIR    tclConfig.sh is in DIR
-  --with-perl             build Perl modules (PL/Perl)
+  --with-perl[=TRUSTWORTHINESS]
+                          build Perl modules (PL/Perl)
   --with-python           build Python modules (PL/Python)
   --with-gssapi           build with GSSAPI support
   --with-krb-srvnam=NAME  default service principal name in Kerberos (GSSAPI)
@@ -8152,26 +8155,62 @@ if test "${with_perl+set}" = set; then :
   withval=$with_perl;
   case $withval in
     yes)
-      :
+
+  PERL_TRUSTED=yes
+  PERL_UNTRUSTED=yes
+
       ;;
     no)
       :
       ;;
     *)
-      as_fn_error $? "no argument expected for --with-perl option" "$LINENO" 5
+      with_perl=yes
+
+  if test "$withval" = trusted ; then
+    PERL_TRUSTED=yes
+    PERL_UNTRUSTED=no
+  elif test "$withval" = untrusted ; then
+    PERL_TRUSTED=no
+    PERL_UNTRUSTED=yes
+  else
+    as_fn_error $? "invalid --with-perl value: argument must be omitted or specified as 'trusted' or 'untrusted'" "$LINENO" 5
+  fi
+
       ;;
   esac
 
 else
   with_perl=no
-
 fi
 
 
+
+if test "$with_perl" = yes; then
+
+  if test "$PERL_TRUSTED" = yes ; then
+
+$as_echo "#define USE_PERL 1" >>confdefs.h
+
+  fi
+  if test "$PERL_UNTRUSTED" = yes ; then
+
+$as_echo "#define USE_PERLU 1" >>confdefs.h
+
+  fi
+
+else
+
+  PERL_TRUSTED=no
+  PERL_UNTRUSTED=no
+
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_perl" >&5
 $as_echo "$with_perl" >&6; }
 
 
+
+
 #
 # Optionally build Python modules (PL/Python)
 #
diff --git a/configure.ac b/configure.ac
index d093fb88dd..0dd440131b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -823,9 +823,39 @@ PGAC_ARG_REQ(with, tclconfig, [DIR], [tclConfig.sh is in DIR])
 # Optionally build Perl modules (PL/Perl)
 #
 AC_MSG_CHECKING([whether to build Perl modules])
-PGAC_ARG_BOOL(with, perl, no, [build Perl modules (PL/Perl)])
+PGAC_ARG_OPTARG(with, perl,
+[TRUSTWORTHINESS], [build Perl modules (PL/Perl)],
+[
+  PERL_TRUSTED=yes
+  PERL_UNTRUSTED=yes
+],
+[
+  if test "$withval" = trusted ; then
+    PERL_TRUSTED=yes
+    PERL_UNTRUSTED=no
+  elif test "$withval" = untrusted ; then
+    PERL_TRUSTED=no
+    PERL_UNTRUSTED=yes
+  else
+    AC_MSG_ERROR([invalid --with-perl value: argument must be omitted or specified as 'trusted' or 'untrusted'])
+  fi
+],
+[
+  if test "$PERL_TRUSTED" = yes ; then
+    AC_DEFINE([USE_PERL], 1, [Define to 1 to build with trusted Perl support. (--with-perl='trusted')])
+  fi
+  if test "$PERL_UNTRUSTED" = yes ; then
+    AC_DEFINE([USE_PERLU], 1, [Define to 1 to build with untrusted Perl support. (--with-perl='untrusted')])
+  fi
+],
+[
+  PERL_TRUSTED=no
+  PERL_UNTRUSTED=no
+])
 AC_MSG_RESULT([$with_perl])
 AC_SUBST(with_perl)
+AC_SUBST(PERL_TRUSTED)
+AC_SUBST(PERL_UNTRUSTED)
 
 #
 # Optionally build Python modules (PL/Python)
diff --git a/contrib/bool_plperl/Makefile b/contrib/bool_plperl/Makefile
index efe1de986b..ae23e7e3f1 100644
--- a/contrib/bool_plperl/Makefile
+++ b/contrib/bool_plperl/Makefile
@@ -8,10 +8,12 @@ PGFILEDESC = "bool_plperl - bool transform for plperl"
 
 PG_CPPFLAGS = -I$(top_srcdir)/src/pl/plperl
 
-EXTENSION = bool_plperlu bool_plperl
-DATA = bool_plperlu--1.0.sql bool_plperl--1.0.sql
-
-REGRESS = bool_plperl bool_plperlu
+# We do not yet know whether we are building with trusted PL/Perl, untrusted
+# PL/Perl, or both, so for now we assume we are just building trusted PL/Perl.
+# We'll adjust these later on if this assumption was accurate.
+EXTENSION = bool_plperl
+DATA = bool_plperl--1.0.sql
+REGRESS = bool_plperl
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
@@ -37,3 +39,17 @@ endif
 
 # As with plperl we need to include the perl_includespec directory last.
 override CPPFLAGS := $(CPPFLAGS) $(perl_embed_ccflags) $(perl_includespec)
+
+# Since we now know whether we are building trusted PL/Perl, untrusted PL/Perl,
+# or both, we should adjust the relevant variables accordingly.
+ifeq ($(PERL_TRUSTED), no)
+	override undefine EXTENSION
+	override undefine DATA
+	override undefine REGRESS
+endif
+
+ifeq ($(PERL_UNTRUSTED), yes)
+	override EXTENSION += bool_plperlu
+	override DATA += bool_plperlu--1.0.sql
+	override REGRESS += bool_plperlu
+endif
diff --git a/contrib/hstore_plperl/Makefile b/contrib/hstore_plperl/Makefile
index 9065f16408..32af5049a9 100644
--- a/contrib/hstore_plperl/Makefile
+++ b/contrib/hstore_plperl/Makefile
@@ -6,11 +6,13 @@ OBJS = \
 	hstore_plperl.o
 PGFILEDESC = "hstore_plperl - hstore transform for plperl"
 
+# We do not yet know whether we are building with trusted PL/Perl, untrusted
+# PL/Perl, or both, so for now we assume we are just building trusted PL/Perl.
+# We'll adjust these later on if this assumption was accurate.
+EXTENSION = hstore_plperl
+DATA = hstore_plperl--1.0.sql
+REGRESS = hstore_plperl create_transform
 
-EXTENSION = hstore_plperl hstore_plperlu
-DATA = hstore_plperl--1.0.sql hstore_plperlu--1.0.sql
-
-REGRESS = hstore_plperl hstore_plperlu create_transform
 EXTRA_INSTALL = contrib/hstore
 
 ifdef USE_PGXS
@@ -39,3 +41,17 @@ endif
 
 # As with plperl we need to include the perl_includespec directory last.
 override CPPFLAGS := $(CPPFLAGS) $(perl_embed_ccflags) $(perl_includespec)
+
+# Since we now know whether we are building trusted PL/Perl, untrusted PL/Perl,
+# or both, we should adjust the relevant variables accordingly.
+ifeq ($(PERL_TRUSTED), no)
+	override undefine EXTENSION
+	override undefine DATA
+	override undefine REGRESS
+endif
+
+ifeq ($(PERL_UNTRUSTED), yes)
+	override EXTENSION += hstore_plperlu
+	override DATA += hstore_plperlu--1.0.sql
+	override REGRESS += hstore_plperlu
+endif
diff --git a/contrib/jsonb_plperl/Makefile b/contrib/jsonb_plperl/Makefile
index ba9480e819..218bd51c9e 100644
--- a/contrib/jsonb_plperl/Makefile
+++ b/contrib/jsonb_plperl/Makefile
@@ -8,10 +8,12 @@ PGFILEDESC = "jsonb_plperl - jsonb transform for plperl"
 
 PG_CPPFLAGS = -I$(top_srcdir)/src/pl/plperl
 
-EXTENSION = jsonb_plperlu jsonb_plperl
-DATA = jsonb_plperlu--1.0.sql jsonb_plperl--1.0.sql
-
-REGRESS = jsonb_plperl jsonb_plperlu
+# We do not yet know whether we are building with trusted PL/Perl, untrusted
+# PL/Perl, or both, so for now we assume we are just building trusted PL/Perl.
+# We'll adjust these later on if this assumption was accurate.
+EXTENSION = jsonb_plperl
+DATA = jsonb_plperl--1.0.sql
+REGRESS = jsonb_plperl
 
 SHLIB_LINK += $(filter -lm, $(LIBS))
 
@@ -39,3 +41,17 @@ endif
 
 # As with plperl we need to include the perl_includespec directory last.
 override CPPFLAGS := $(CPPFLAGS) $(perl_embed_ccflags) $(perl_includespec)
+
+# Since we now know whether we are building trusted PL/Perl, untrusted PL/Perl,
+# or both, we should adjust the relevant variables accordingly.
+ifeq ($(PERL_TRUSTED), no)
+    override undefine EXTENSION
+    override undefine DATA
+    override undefine REGRESS
+endif
+
+ifeq ($(PERL_UNTRUSTED), yes)
+    override EXTENSION += jsonb_plperlu
+    override DATA += jsonb_plperlu--1.0.sql
+    override REGRESS += jsonb_plperlu
+endif
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index c585078029..4377e9d51a 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -873,10 +873,31 @@ build-postgresql:
       </varlistentry>
 
       <varlistentry>
-       <term><option>--with-perl</option></term>
+       <term><option>--with-perl<optional>=<replaceable>TRUSTWORTHINESS</replaceable></optional></option></term>
        <listitem>
         <para>
          Build the <application>PL/Perl</application> server-side language.
+         <replaceable>TRUSTWORTHINESS</replaceable> is an optional argument and,
+         if provided, must be one of:
+        </para>
+        <itemizedlist>
+         <listitem>
+          <para>
+           <option>trusted</option> to build only trusted
+           <application>PL/Perl</application>
+          </para>
+         </listitem>
+         <listitem>
+          <para>
+           <option>untrusted</option> to build only untrusted
+           <application>PL/Perl</application>
+           (<application>PL/PerlU</application>)
+          </para>
+         </listitem>
+        </itemizedlist>
+        <para>
+         If <replaceable>TRUSTWORTHINESS</replaceable> is not specified, both
+         trusted and untrusted <application>PL/Perl</application> will be built.
         </para>
        </listitem>
       </varlistentry>
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 051718e4fe..53f367ca7a 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -526,6 +526,8 @@ GENHTML = @GENHTML@
 
 DEF_PGPORT = @default_port@
 WANTED_LANGUAGES = @WANTED_LANGUAGES@
+PERL_TRUSTED = @PERL_TRUSTED@
+PERL_UNTRUSTED = @PERL_UNTRUSTED@
 
 
 ##########################################################################
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index cdd742cb55..2779f5f671 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -931,6 +931,12 @@
 /* Define to 1 to build with PAM support. (--with-pam) */
 #undef USE_PAM
 
+/* Define to 1 to build with trusted Perl support. (--with-perl='trusted') */
+#undef USE_PERL
+
+/* Define to 1 to build with untrusted Perl support. (--with-perl='untrusted') */
+#undef USE_PERLU
+
 /* Define to 1 to use software CRC-32C implementation (slicing-by-8). */
 #undef USE_SLICING_BY_8_CRC32C
 
diff --git a/src/pl/plperl/GNUmakefile b/src/pl/plperl/GNUmakefile
index a2e6410f53..d01201bbac 100644
--- a/src/pl/plperl/GNUmakefile
+++ b/src/pl/plperl/GNUmakefile
@@ -27,8 +27,13 @@ NAME = plperl
 
 OBJS = plperl.o SPI.o Util.o $(WIN32RES)
 
-DATA = plperl.control plperl--1.0.sql \
-       plperlu.control plperlu--1.0.sql
+ifeq ($(PERL_TRUSTED), yes)
+	DATA += plperl.control plperl--1.0.sql
+endif
+
+ifeq ($(PERL_UNTRUSTED), yes)
+	DATA += plperlu.control plperlu--1.0.sql
+endif
 
 PERLCHUNKS = plc_perlboot.pl plc_trusted.pl
 
@@ -56,14 +61,26 @@ endif # win32
 SHLIB_LINK = $(perl_embed_ldflags)
 
 REGRESS_OPTS = --dbname=$(PL_TESTDB)
-REGRESS = plperl_setup plperl plperl_lc plperl_trigger plperl_shared \
-	plperl_elog plperl_util plperl_init plperlu plperl_array \
-	plperl_call plperl_transaction
-# if Perl can support two interpreters in one backend,
-# test plperl-and-plperlu cases
-ifneq ($(PERL),)
-ifeq ($(shell $(PERL) -V:usemultiplicity), usemultiplicity='define';)
-	REGRESS += plperl_plperlu
+
+ifeq ($(PERL_TRUSTED), yes)
+	REGRESS = plperl_setup plperl plperl_lc plperl_trigger plperl_shared \
+		plperl_elog plperl_util plperl_init plperl_array plperl_call \
+		plperl_transaction
+endif
+
+ifeq ($(PERL_UNTRUSTED), yes)
+	REGRESS += plperlu
+endif
+
+ifeq ($(PERL_TRUSTED), yes)
+ifeq ($(PERL_UNTRUSTED), yes)
+	# if Perl can support two interpreters in one backend,
+	# test plperl-and-plperlu cases
+	ifneq ($(PERL),)
+		ifeq ($(shell $(PERL) -V:usemultiplicity), usemultiplicity='define';)
+			REGRESS += plperl_plperlu
+		endif
+	endif
 endif
 endif
 
diff --git a/src/pl/plperl/expected/plperl_setup.out b/src/pl/plperl/expected/plperl_setup.out
index 5234febefd..d0682325b2 100644
--- a/src/pl/plperl/expected/plperl_setup.out
+++ b/src/pl/plperl/expected/plperl_setup.out
@@ -1,18 +1,15 @@
 --
--- Install the plperl and plperlu extensions
+-- Install plperl
 --
 -- Before going ahead with the to-be-tested installations, verify that
--- a non-superuser is allowed to install plperl (but not plperlu) when
--- suitable permissions have been granted.
+-- a non-superuser is allowed to install plperl when suitable permissions
+-- have been granted.
 CREATE USER regress_user1;
 CREATE USER regress_user2;
 SET ROLE regress_user1;
 CREATE EXTENSION plperl;  -- fail
 ERROR:  permission denied to create extension "plperl"
 HINT:  Must have CREATE privilege on current database to create this extension.
-CREATE EXTENSION plperlu;  -- fail
-ERROR:  permission denied to create extension "plperlu"
-HINT:  Must be superuser to create this extension.
 RESET ROLE;
 DO $$
 begin
@@ -22,9 +19,6 @@ end;
 $$;
 SET ROLE regress_user1;
 CREATE EXTENSION plperl;
-CREATE EXTENSION plperlu;  -- fail
-ERROR:  permission denied to create extension "plperlu"
-HINT:  Must be superuser to create this extension.
 CREATE SCHEMA plperl_setup_scratch;
 SET search_path = plperl_setup_scratch;
 GRANT ALL ON SCHEMA plperl_setup_scratch TO regress_user2;
@@ -68,6 +62,5 @@ RESET ROLE;
 DROP OWNED BY regress_user1;
 DROP USER regress_user1;
 DROP USER regress_user2;
--- Now install the versions that will be used by subsequent test scripts.
+-- Now install the version that will be used by subsequent test scripts.
 CREATE EXTENSION plperl;
-CREATE EXTENSION plperlu;
diff --git a/src/pl/plperl/expected/plperlu.out b/src/pl/plperl/expected/plperlu.out
index a3edb38497..f759466a90 100644
--- a/src/pl/plperl/expected/plperlu.out
+++ b/src/pl/plperl/expected/plperlu.out
@@ -1,5 +1,32 @@
+-- Before going ahead with the to-be-tested installations, verify that
+-- only superusers can install plperlu.
+CREATE USER regress_user1;
+SET ROLE regress_user1;
+CREATE EXTENSION plperlu;  -- fail
+ERROR:  permission denied to create extension "plperlu"
+HINT:  Must be superuser to create this extension.
+RESET ROLE;
+DO $$
+begin
+  execute format('grant create on database %I to regress_user1',
+                 current_database());
+end;
+$$;
+SET ROLE regress_user1;
+CREATE EXTENSION plperlu;  -- fail
+ERROR:  permission denied to create extension "plperlu"
+HINT:  Must be superuser to create this extension.
+RESET ROLE;
+DO $$
+begin
+  execute format('revoke create on database %I from regress_user1',
+                 current_database());
+end;
+$$;
+DROP ROLE regress_user1;
 -- Use ONLY plperlu tests here. For plperl/plerlu combined tests
 -- see plperl_plperlu.sql
+CREATE EXTENSION plperlu;
 -- This test tests setting on_plperlu_init after loading plperl
 LOAD 'plperl';
 -- Test plperl.on_plperlu_init gets run
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 9bc6793a30..ff5f9641d5 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -445,6 +445,7 @@ _PG_init(void)
 	 * OK since the worst result would be an error.  Your code oughta pass
 	 * use_strict anyway ;-)
 	 */
+#ifdef USE_PERL
 	DefineCustomStringVariable("plperl.on_plperl_init",
 							   gettext_noop("Perl initialization code to execute once when plperl is first used."),
 							   NULL,
@@ -452,7 +453,9 @@ _PG_init(void)
 							   NULL,
 							   PGC_SUSET, 0,
 							   NULL, NULL, NULL);
+#endif  /* USE_PERL */
 
+#ifdef USE_PERLU
 	DefineCustomStringVariable("plperl.on_plperlu_init",
 							   gettext_noop("Perl initialization code to execute once when plperlu is first used."),
 							   NULL,
@@ -460,6 +463,7 @@ _PG_init(void)
 							   NULL,
 							   PGC_SUSET, 0,
 							   NULL, NULL, NULL);
+#endif  /* USE_PERLU */
 
 	MarkGUCPrefixReserved("plperl");
 
@@ -2039,6 +2043,7 @@ plperl_validator_internal(PG_FUNCTION_ARGS, bool trusted)
  * There are three externally visible pieces to plperl: plperl_call_handler,
  * plperl_inline_handler, and plperl_validator.
  */
+#ifdef USE_PERL
 
 PG_FUNCTION_INFO_V1(plperl_call_handler);
 
@@ -2064,11 +2069,14 @@ plperl_validator(PG_FUNCTION_ARGS)
 	return plperl_validator_internal(fcinfo, true);
 }
 
+#endif  /* USE_PERL */
+
 
 /*
  * plperlu likewise requires three externally visible functions:
  * plperlu_call_handler, plperlu_inline_handler, and plperlu_validator.
  */
+#ifdef USE_PERLU
 
 PG_FUNCTION_INFO_V1(plperlu_call_handler);
 
@@ -2095,6 +2103,8 @@ plperlu_validator(PG_FUNCTION_ARGS)
 	return plperl_validator_internal(fcinfo, false);
 }
 
+#endif  /* USE_PERLU */
+
 
 /*
  * Uses mkfunc to create a subroutine whose text is
diff --git a/src/pl/plperl/sql/plperl_setup.sql b/src/pl/plperl/sql/plperl_setup.sql
index a89cf56617..eb29cacdac 100644
--- a/src/pl/plperl/sql/plperl_setup.sql
+++ b/src/pl/plperl/sql/plperl_setup.sql
@@ -1,10 +1,10 @@
 --
--- Install the plperl and plperlu extensions
+-- Install plperl
 --
 
 -- Before going ahead with the to-be-tested installations, verify that
--- a non-superuser is allowed to install plperl (but not plperlu) when
--- suitable permissions have been granted.
+-- a non-superuser is allowed to install plperl when suitable permissions
+-- have been granted.
 
 CREATE USER regress_user1;
 CREATE USER regress_user2;
@@ -12,7 +12,6 @@ CREATE USER regress_user2;
 SET ROLE regress_user1;
 
 CREATE EXTENSION plperl;  -- fail
-CREATE EXTENSION plperlu;  -- fail
 
 RESET ROLE;
 
@@ -26,7 +25,6 @@ $$;
 SET ROLE regress_user1;
 
 CREATE EXTENSION plperl;
-CREATE EXTENSION plperlu;  -- fail
 CREATE SCHEMA plperl_setup_scratch;
 SET search_path = plperl_setup_scratch;
 GRANT ALL ON SCHEMA plperl_setup_scratch TO regress_user2;
@@ -68,6 +66,5 @@ DROP OWNED BY regress_user1;
 DROP USER regress_user1;
 DROP USER regress_user2;
 
--- Now install the versions that will be used by subsequent test scripts.
+-- Now install the version that will be used by subsequent test scripts.
 CREATE EXTENSION plperl;
-CREATE EXTENSION plperlu;
diff --git a/src/pl/plperl/sql/plperlu.sql b/src/pl/plperl/sql/plperlu.sql
index be43df5d90..1e050e8237 100644
--- a/src/pl/plperl/sql/plperlu.sql
+++ b/src/pl/plperl/sql/plperlu.sql
@@ -1,5 +1,34 @@
+-- Before going ahead with the to-be-tested installations, verify that
+-- only superusers can install plperlu.
+CREATE USER regress_user1;
+
+SET ROLE regress_user1;
+CREATE EXTENSION plperlu;  -- fail
+RESET ROLE;
+
+DO $$
+begin
+  execute format('grant create on database %I to regress_user1',
+                 current_database());
+end;
+$$;
+
+SET ROLE regress_user1;
+CREATE EXTENSION plperlu;  -- fail
+RESET ROLE;
+
+DO $$
+begin
+  execute format('revoke create on database %I from regress_user1',
+                 current_database());
+end;
+$$;
+
+DROP ROLE regress_user1;
+
 -- Use ONLY plperlu tests here. For plperl/plerlu combined tests
 -- see plperl_plperlu.sql
+CREATE EXTENSION plperlu;
 
 -- This test tests setting on_plperlu_init after loading plperl
 LOAD 'plperl';
-- 
2.25.1

