]> granicus.if.org Git - postgresql/commitdiff
Create extension infrastructure for the core procedural languages.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 5 Mar 2011 02:51:14 +0000 (21:51 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 5 Mar 2011 02:51:14 +0000 (21:51 -0500)
This mostly just involves creating control, install, and
update-from-unpackaged scripts for them.  However, I had to adjust plperl
and plpython to not share the same support functions between variants,
because we can't put the same function into multiple extensions.

catversion bump forced due to new contents of pg_pltemplate, and because
initdb now installs plpgsql as an extension not a bare language.

Add support for regression testing these as extensions not bare
languages.

Fix a couple of other issues that popped up while testing this: my initial
hack at pg_dump binary-upgrade support didn't work right, and we don't want
an extra schema permissions test after all.

Documentation changes still to come, but I'm committing now to see
whether the MSVC build scripts need work (likely they do).

41 files changed:
src/backend/commands/extension.c
src/bin/initdb/initdb.c
src/bin/pg_dump/pg_dump.c
src/include/catalog/catversion.h
src/include/catalog/pg_pltemplate.h
src/pl/plperl/GNUmakefile
src/pl/plperl/plperl--1.0.sql [new file with mode: 0644]
src/pl/plperl/plperl--unpackaged--1.0.sql [new file with mode: 0644]
src/pl/plperl/plperl.c
src/pl/plperl/plperl.control [new file with mode: 0644]
src/pl/plperl/plperlu--1.0.sql [new file with mode: 0644]
src/pl/plperl/plperlu--unpackaged--1.0.sql [new file with mode: 0644]
src/pl/plperl/plperlu.control [new file with mode: 0644]
src/pl/plpgsql/src/Makefile
src/pl/plpgsql/src/plpgsql--1.0.sql [new file with mode: 0644]
src/pl/plpgsql/src/plpgsql--unpackaged--1.0.sql [new file with mode: 0644]
src/pl/plpgsql/src/plpgsql.control [new file with mode: 0644]
src/pl/plpython/Makefile
src/pl/plpython/expected/plpython_drop.out
src/pl/plpython/expected/plpython_test.out
src/pl/plpython/plpython.c
src/pl/plpython/plpython2u--1.0.sql [new file with mode: 0644]
src/pl/plpython/plpython2u--unpackaged--1.0.sql [new file with mode: 0644]
src/pl/plpython/plpython2u.control [new file with mode: 0644]
src/pl/plpython/plpython3u--1.0.sql [new file with mode: 0644]
src/pl/plpython/plpython3u--unpackaged--1.0.sql [new file with mode: 0644]
src/pl/plpython/plpython3u.control [new file with mode: 0644]
src/pl/plpython/plpythonu--1.0.sql [new file with mode: 0644]
src/pl/plpython/plpythonu--unpackaged--1.0.sql [new file with mode: 0644]
src/pl/plpython/plpythonu.control [new file with mode: 0644]
src/pl/plpython/sql/plpython_drop.sql
src/pl/plpython/sql/plpython_test.sql
src/pl/tcl/Makefile
src/pl/tcl/pltcl--1.0.sql [new file with mode: 0644]
src/pl/tcl/pltcl--unpackaged--1.0.sql [new file with mode: 0644]
src/pl/tcl/pltcl.control [new file with mode: 0644]
src/pl/tcl/pltclu--1.0.sql [new file with mode: 0644]
src/pl/tcl/pltclu--unpackaged--1.0.sql [new file with mode: 0644]
src/pl/tcl/pltclu.control [new file with mode: 0644]
src/test/regress/pg_regress.c
src/tools/msvc/vcregress.pl

index 6ff30ddc0ae67c4b4e92214756156b351ac8dea1..b1673e6549a0ac945d9971d357ad07e559323c40 100644 (file)
@@ -1188,7 +1188,6 @@ CreateExtension(CreateExtensionStmt *stmt)
        List       *requiredExtensions;
        List       *requiredSchemas;
        Oid                     extensionOid;
-       AclResult       aclresult;
        ListCell   *lc;
 
        /* Check extension name validity before any filesystem access */
@@ -1393,13 +1392,13 @@ CreateExtension(CreateExtensionStmt *stmt)
        }
 
        /*
-        * Check we have creation rights in target namespace.  Although strictly
-        * speaking the extension itself isn't in the schema, it will almost
-        * certainly want to create objects therein, so let's just check now.
+        * We don't check creation rights on the target namespace here.  If the
+        * extension script actually creates any objects there, it will fail if
+        * the user doesn't have such permissions.  But there are cases such as
+        * procedural languages where it's convenient to set schema = pg_catalog
+        * yet we don't want to restrict the command to users with ACL_CREATE
+        * for pg_catalog.
         */
-       aclresult = pg_namespace_aclcheck(schemaOid, extowner, ACL_CREATE);
-       if (aclresult != ACLCHECK_OK)
-               aclcheck_error(aclresult, ACL_KIND_NAMESPACE, schemaName);
 
        /*
         * Look up the prerequisite extensions, and build lists of their OIDs
index 98915c4b8914b9fd9a0b85ed45f9790a5328e5a2..ce24d6101d13832e876e002b2d775e11fa94b60b 100644 (file)
@@ -1912,7 +1912,7 @@ load_plpgsql(void)
 
        PG_CMD_OPEN;
 
-       PG_CMD_PUTS("CREATE LANGUAGE plpgsql;\n");
+       PG_CMD_PUTS("CREATE EXTENSION plpgsql;\n");
 
        PG_CMD_CLOSE;
 
index ea1818b1d574d107e93015a14e01f86ade46e2f4..dfbdcadd1453f72815f41c5e91a92ee3a2693afc 100644 (file)
@@ -1171,6 +1171,24 @@ selectDumpableDefaultACL(DefaultACLInfo *dinfo)
                dinfo->dobj.dump = include_everything;
 }
 
+/*
+ * selectDumpableExtension: policy-setting subroutine
+ *             Mark an extension as to be dumped or not
+ *
+ * Normally, we just dump all extensions.  However, in binary-upgrade mode
+ * it's necessary to skip built-in extensions, since we assume those will
+ * already be installed in the target database.  We identify such extensions
+ * by their having OIDs in the range reserved for initdb.
+ */
+static void
+selectDumpableExtension(ExtensionInfo *extinfo)
+{
+       if (binary_upgrade && extinfo->dobj.catId.oid < (Oid) FirstNormalObjectId)
+               extinfo->dobj.dump = false;
+       else
+               extinfo->dobj.dump = true;
+}
+
 /*
  * selectDumpableObject: policy-setting subroutine
  *             Mark a generic dumpable object as to be dumped or not
@@ -2730,6 +2748,9 @@ getExtensions(int *numExtensions)
                extinfo[i].extversion = strdup(PQgetvalue(res, i, i_extversion));
                extinfo[i].extconfig = strdup(PQgetvalue(res, i, i_extconfig));
                extinfo[i].extcondition = strdup(PQgetvalue(res, i, i_extcondition));
+
+               /* Decide whether we want to dump it */
+               selectDumpableExtension(&(extinfo[i]));
        }
 
        PQclear(res);
@@ -7042,19 +7063,6 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
        if (!extinfo->dobj.dump || dataOnly)
                return;
 
-       /*
-        * In a regular dump, we use IF NOT EXISTS so that there isn't a problem
-        * if the extension already exists in the target database; this is
-        * essential for installed-by-default extensions such as plpgsql.
-        *
-        * In binary-upgrade mode, that doesn't work well, so instead we skip
-        * extensions with OIDs less than FirstNormalObjectId; those were
-        * presumably installed by initdb, and we assume they'll exist in the
-        * target installation too.
-        */
-       if (binary_upgrade && extinfo->dobj.catId.oid < (Oid) FirstNormalObjectId)
-               return;
-
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
        labelq = createPQExpBuffer();
@@ -7065,6 +7073,16 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
 
        if (!binary_upgrade)
        {
+               /*
+                * In a regular dump, we use IF NOT EXISTS so that there isn't a
+                * problem if the extension already exists in the target database;
+                * this is essential for installed-by-default extensions such as
+                * plpgsql.
+                *
+                * In binary-upgrade mode, that doesn't work well, so instead we skip
+                * built-in extensions based on their OIDs; see
+                * selectDumpableExtension.
+                */
                appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
                                                  qextname, fmtId(extinfo->namespace));
        }
index fe7ccf4ba0ba1c3ce7114dcb949bdf29ae32f737..56fb4931ba7c56884d31b9457499c6d51555e182 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201103041
+#define CATALOG_VERSION_NO     201103042
 
 #endif
index c0578f92c098d7115b1926b4d0088a6387b85ad5..fa086525e7ffe4488a7c66af2eb6c62b63d2c99a 100644 (file)
@@ -71,9 +71,9 @@ DATA(insert ( "plpgsql"               t t "plpgsql_call_handler" "plpgsql_inline_handler" "pl
 DATA(insert ( "pltcl"          t t "pltcl_call_handler" _null_ _null_ "$libdir/pltcl" _null_ ));
 DATA(insert ( "pltclu"         f f "pltclu_call_handler" _null_ _null_ "$libdir/pltcl" _null_ ));
 DATA(insert ( "plperl"         t t "plperl_call_handler" "plperl_inline_handler" "plperl_validator" "$libdir/plperl" _null_ ));
-DATA(insert ( "plperlu"                f f "plperl_call_handler" "plperl_inline_handler" "plperl_validator" "$libdir/plperl" _null_ ));
+DATA(insert ( "plperlu"                f f "plperlu_call_handler" "plperlu_inline_handler" "plperlu_validator" "$libdir/plperl" _null_ ));
 DATA(insert ( "plpythonu"      f f "plpython_call_handler" "plpython_inline_handler" "plpython_validator" "$libdir/plpython" _null_ ));
-DATA(insert ( "plpython2u"     f f "plpython_call_handler" "plpython_inline_handler" "plpython_validator" "$libdir/plpython2" _null_ ));
+DATA(insert ( "plpython2u"     f f "plpython2_call_handler" "plpython2_inline_handler" "plpython2_validator" "$libdir/plpython2" _null_ ));
 DATA(insert ( "plpython3u"     f f "plpython3_call_handler" "plpython3_inline_handler" "plpython3_validator" "$libdir/plpython3" _null_ ));
 
 #endif   /* PG_PLTEMPLATE_H */
index e86cb84dba22734686390c2586b2cb7aa2f873c3..71e2cef4c5ecb553aa5b9b91afa962302f6c247a 100644 (file)
@@ -36,11 +36,14 @@ NAME = plperl
 
 OBJS = plperl.o SPI.o Util.o
 
+DATA = plperl.control plperl--1.0.sql plperl--unpackaged--1.0.sql \
+       plperlu.control plperlu--1.0.sql plperlu--unpackaged--1.0.sql
+
 PERLCHUNKS = plc_perlboot.pl plc_trusted.pl
 
 SHLIB_LINK = $(perl_embed_ldflags)
 
-REGRESS_OPTS = --dbname=$(PL_TESTDB) --load-language=plperl  --load-language=plperlu
+REGRESS_OPTS = --dbname=$(PL_TESTDB) --load-extension=plperl  --load-extension=plperlu
 REGRESS = plperl plperl_trigger plperl_shared plperl_elog plperl_util plperl_init plperlu plperl_array
 # if Perl can support two interpreters in one backend,
 # test plperl-and-plperlu cases
@@ -70,11 +73,25 @@ SPI.c: SPI.xs
 Util.c: Util.xs
        $(PERL) $(perl_privlibexp)/ExtUtils/xsubpp -typemap $(perl_privlibexp)/ExtUtils/typemap $< >$@
 
-install: all installdirs install-lib
+
+install: all installdirs install-lib install-data
 
 installdirs: installdirs-lib
+       $(MKDIR_P) '$(DESTDIR)$(datadir)/extension'
+
+uninstall: uninstall-lib uninstall-data
+
+install-data:
+       @for file in $(addprefix $(srcdir)/, $(DATA)); do \
+         echo "$(INSTALL_DATA) $$file '$(DESTDIR)$(datadir)/extension'"; \
+         $(INSTALL_DATA) $$file '$(DESTDIR)$(datadir)/extension'; \
+       done
+
+uninstall-data:
+       rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA)))
+
+.PHONY: install-data uninstall-data
 
-uninstall: uninstall-lib
 
 check: submake
        $(pg_regress_check) $(REGRESS_OPTS) $(REGRESS)
diff --git a/src/pl/plperl/plperl--1.0.sql b/src/pl/plperl/plperl--1.0.sql
new file mode 100644 (file)
index 0000000..befd882
--- /dev/null
@@ -0,0 +1,9 @@
+/* src/pl/plperl/plperl--1.0.sql */
+
+/*
+ * Currently, all the interesting stuff is done by CREATE LANGUAGE.
+ * Later we will probably "dumb down" that command and put more of the
+ * knowledge into this script.
+ */
+
+CREATE PROCEDURAL LANGUAGE plperl;
diff --git a/src/pl/plperl/plperl--unpackaged--1.0.sql b/src/pl/plperl/plperl--unpackaged--1.0.sql
new file mode 100644 (file)
index 0000000..b062bd5
--- /dev/null
@@ -0,0 +1,7 @@
+/* src/pl/plperl/plperl--unpackaged--1.0.sql */
+
+ALTER EXTENSION plperl ADD PROCEDURAL LANGUAGE plperl;
+-- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to.
+ALTER EXTENSION plperl ADD FUNCTION plperl_call_handler();
+ALTER EXTENSION plperl ADD FUNCTION plperl_inline_handler(internal);
+ALTER EXTENSION plperl ADD FUNCTION plperl_validator(oid);
index 72e1e5106a679a463db19c61ae96ef321eb309f2..9a94b3f085236d4333eb1a80a8e1d19dcb891681 100644 (file)
@@ -222,6 +222,9 @@ static plperl_call_data *current_call_data = NULL;
 Datum          plperl_call_handler(PG_FUNCTION_ARGS);
 Datum          plperl_inline_handler(PG_FUNCTION_ARGS);
 Datum          plperl_validator(PG_FUNCTION_ARGS);
+Datum          plperlu_call_handler(PG_FUNCTION_ARGS);
+Datum          plperlu_inline_handler(PG_FUNCTION_ARGS);
+Datum          plperlu_validator(PG_FUNCTION_ARGS);
 void           _PG_init(void);
 
 static PerlInterpreter *plperl_init_interp(void);
@@ -1758,6 +1761,39 @@ plperl_validator(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * plperlu likewise requires three externally visible functions:
+ * plperlu_call_handler, plperlu_inline_handler, and plperlu_validator.
+ * These are currently just aliases that send control to the plperl
+ * handler functions, and we decide whether a particular function is
+ * trusted or not by inspecting the actual pg_language tuple.
+ */
+
+PG_FUNCTION_INFO_V1(plperlu_call_handler);
+
+Datum
+plperlu_call_handler(PG_FUNCTION_ARGS)
+{
+       return plperl_call_handler(fcinfo);
+}
+
+PG_FUNCTION_INFO_V1(plperlu_inline_handler);
+
+Datum
+plperlu_inline_handler(PG_FUNCTION_ARGS)
+{
+       return plperl_inline_handler(fcinfo);
+}
+
+PG_FUNCTION_INFO_V1(plperlu_validator);
+
+Datum
+plperlu_validator(PG_FUNCTION_ARGS)
+{
+       return plperl_validator(fcinfo);
+}
+
+
 /*
  * Uses mksafefunc/mkunsafefunc to create a subroutine whose text is
  * supplied in s, and returns a reference to it
diff --git a/src/pl/plperl/plperl.control b/src/pl/plperl/plperl.control
new file mode 100644 (file)
index 0000000..6faace1
--- /dev/null
@@ -0,0 +1,7 @@
+# plperl extension
+comment = 'PL/Perl procedural language'
+default_version = '1.0'
+module_pathname = '$libdir/plperl'
+relocatable = false
+schema = pg_catalog
+superuser = false
diff --git a/src/pl/plperl/plperlu--1.0.sql b/src/pl/plperl/plperlu--1.0.sql
new file mode 100644 (file)
index 0000000..025f795
--- /dev/null
@@ -0,0 +1,9 @@
+/* src/pl/plperl/plperlu--1.0.sql */
+
+/*
+ * Currently, all the interesting stuff is done by CREATE LANGUAGE.
+ * Later we will probably "dumb down" that command and put more of the
+ * knowledge into this script.
+ */
+
+CREATE PROCEDURAL LANGUAGE plperlu;
diff --git a/src/pl/plperl/plperlu--unpackaged--1.0.sql b/src/pl/plperl/plperlu--unpackaged--1.0.sql
new file mode 100644 (file)
index 0000000..bc62d36
--- /dev/null
@@ -0,0 +1,7 @@
+/* src/pl/plperl/plperlu--unpackaged--1.0.sql */
+
+ALTER EXTENSION plperlu ADD PROCEDURAL LANGUAGE plperlu;
+-- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to.
+ALTER EXTENSION plperlu ADD FUNCTION plperlu_call_handler();
+ALTER EXTENSION plperlu ADD FUNCTION plperlu_inline_handler(internal);
+ALTER EXTENSION plperlu ADD FUNCTION plperlu_validator(oid);
diff --git a/src/pl/plperl/plperlu.control b/src/pl/plperl/plperlu.control
new file mode 100644 (file)
index 0000000..69473ca
--- /dev/null
@@ -0,0 +1,7 @@
+# plperlu extension
+comment = 'PL/PerlU untrusted procedural language'
+default_version = '1.0'
+module_pathname = '$libdir/plperl'
+relocatable = false
+schema = pg_catalog
+superuser = true
index a5f161dc62d76d706fae7bf36f7b5ba11a6e1b93..d748ef682621f3b5fa2410130aa4e030ff1c08fc 100644 (file)
@@ -1,6 +1,6 @@
 #-------------------------------------------------------------------------
 #
-# Makefile for the plpgsql shared object
+# Makefile for the pl/pgsql procedural language
 #
 # src/pl/plpgsql/src/Makefile
 #
@@ -19,17 +19,31 @@ rpath =
 
 OBJS = pl_gram.o pl_handler.o pl_comp.o pl_exec.o pl_funcs.o pl_scanner.o
 
+DATA = plpgsql.control plpgsql--1.0.sql plpgsql--unpackaged--1.0.sql
+
 all: all-lib
 
 # Shared library stuff
 include $(top_srcdir)/src/Makefile.shlib
 
 
-install: installdirs all install-lib
+install: all installdirs install-lib install-data
 
 installdirs: installdirs-lib
+       $(MKDIR_P) '$(DESTDIR)$(datadir)/extension'
+
+uninstall: uninstall-lib uninstall-data
+
+install-data:
+       @for file in $(addprefix $(srcdir)/, $(DATA)); do \
+         echo "$(INSTALL_DATA) $$file '$(DESTDIR)$(datadir)/extension'"; \
+         $(INSTALL_DATA) $$file '$(DESTDIR)$(datadir)/extension'; \
+       done
+
+uninstall-data:
+       rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA)))
 
-uninstall: uninstall-lib
+.PHONY: install-data uninstall-data
 
 
 # Force these dependencies to be known even without dependency info built:
diff --git a/src/pl/plpgsql/src/plpgsql--1.0.sql b/src/pl/plpgsql/src/plpgsql--1.0.sql
new file mode 100644 (file)
index 0000000..514562d
--- /dev/null
@@ -0,0 +1,9 @@
+/* src/pl/plpgsql/src/plpgsql--1.0.sql */
+
+/*
+ * Currently, all the interesting stuff is done by CREATE LANGUAGE.
+ * Later we will probably "dumb down" that command and put more of the
+ * knowledge into this script.
+ */
+
+CREATE PROCEDURAL LANGUAGE plpgsql;
diff --git a/src/pl/plpgsql/src/plpgsql--unpackaged--1.0.sql b/src/pl/plpgsql/src/plpgsql--unpackaged--1.0.sql
new file mode 100644 (file)
index 0000000..9de7e83
--- /dev/null
@@ -0,0 +1,7 @@
+/* src/pl/plpgsql/src/plpgsql--unpackaged--1.0.sql */
+
+ALTER EXTENSION plpgsql ADD PROCEDURAL LANGUAGE plpgsql;
+-- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to.
+ALTER EXTENSION plpgsql ADD FUNCTION plpgsql_call_handler();
+ALTER EXTENSION plpgsql ADD FUNCTION plpgsql_inline_handler(internal);
+ALTER EXTENSION plpgsql ADD FUNCTION plpgsql_validator(oid);
diff --git a/src/pl/plpgsql/src/plpgsql.control b/src/pl/plpgsql/src/plpgsql.control
new file mode 100644 (file)
index 0000000..b320227
--- /dev/null
@@ -0,0 +1,7 @@
+# plpgsql extension
+comment = 'PL/pgSQL procedural language'
+default_version = '1.0'
+module_pathname = '$libdir/plpgsql'
+relocatable = false
+schema = pg_catalog
+superuser = false
index e6b6ed3ca5262dc3dd9e158b8c10694d77d75618..46e0195142424a8ec594c5202ee46aa6c60941ec 100644 (file)
@@ -37,8 +37,13 @@ override CPPFLAGS := -I. -I$(srcdir) $(python_includespec) $(CPPFLAGS)
 rpathdir = $(python_libdir)
 
 NAME = plpython$(python_majorversion)
+
 OBJS = plpython.o
 
+DATA = plpythonu.control plpythonu--1.0.sql plpythonu--unpackaged--1.0.sql \
+       plpython2u.control plpython2u--1.0.sql plpython2u--unpackaged--1.0.sql \
+       plpython3u.control plpython3u--1.0.sql plpython3u--unpackaged--1.0.sql
+
 
 # Python on win32 ships with import libraries only for Microsoft Visual C++,
 # which are not compatible with mingw gcc. Therefore we need to build a
@@ -60,7 +65,7 @@ REGRESS_OPTS = --dbname=$(PL_TESTDB)
 # Only load plpythonu with Python 2.  The test files themselves load
 # the versioned language plpython(2|3)u.
 ifeq ($(python_majorversion),2)
-REGRESS_OPTS += --load-language=plpythonu
+REGRESS_OPTS += --load-extension=plpythonu
 endif
 REGRESS = \
        plpython_schema \
@@ -98,18 +103,32 @@ all: all-lib
 
 distprep: spiexceptions.h
 
-install: all installdirs install-lib
+
+install: all installdirs install-lib install-data
 ifeq ($(python_majorversion),2)
        cd '$(DESTDIR)$(pkglibdir)' && rm -f plpython$(DLSUFFIX) && $(LN_S) $(shlib) plpython$(DLSUFFIX)
 endif
 
 installdirs: installdirs-lib
+       $(MKDIR_P) '$(DESTDIR)$(datadir)/extension'
 
-uninstall: uninstall-lib
+uninstall: uninstall-lib uninstall-data
 ifeq ($(python_majorversion),2)
        rm -f '$(DESTDIR)$(pkglibdir)/plpython$(DLSUFFIX)'
 endif
 
+install-data:
+       @for file in $(addprefix $(srcdir)/, $(DATA)); do \
+         echo "$(INSTALL_DATA) $$file '$(DESTDIR)$(datadir)/extension'"; \
+         $(INSTALL_DATA) $$file '$(DESTDIR)$(datadir)/extension'; \
+       done
+
+uninstall-data:
+       rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA)))
+
+.PHONY: install-data uninstall-data
+
+
 ifeq ($(python_majorversion),3)
 # Adjust regression tests for Python 3 compatibility
 prep3:
@@ -124,6 +143,8 @@ prep3:
              -e "s/def next/def __next__/g" \
              -e "s/LANGUAGE plpythonu/LANGUAGE plpython3u/g" \
              -e "s/LANGUAGE plpython2u/LANGUAGE plpython3u/g" \
+             -e "s/EXTENSION plpythonu/EXTENSION plpython3u/g" \
+             -e "s/EXTENSION plpython2u/EXTENSION plpython3u/g" \
            $$file >`echo $$file | sed 's,$(srcdir),python3,'`; \
        done
 
index fef642f7c06f8655875a82efcfe199191843466f..a0e3b5c4ef64bf8cfaf5adb288971eb6202c536e 100644 (file)
@@ -2,4 +2,5 @@
 -- For paranoia's sake, don't leave an untrusted language sitting around
 --
 SET client_min_messages = WARNING;
-DROP PROCEDURAL LANGUAGE plpythonu CASCADE;
+DROP EXTENSION plpythonu CASCADE;
+DROP EXTENSION IF EXISTS plpython2u CASCADE;
index 7b2e1703f4bc5ed82a0beddf1fd6696778d0896b..c2358b452d9472e571a71d24681c921cbfeff375 100644 (file)
@@ -1,5 +1,5 @@
 -- first some tests of basic functionality
-CREATE LANGUAGE plpython2u;
+CREATE EXTENSION plpython2u;
 -- really stupid function just to get the module loaded
 CREATE FUNCTION stupid() RETURNS text AS 'return "zarkon"' LANGUAGE plpythonu;
 select stupid();
index 75f7b5cf57fc371ce4a38e6eb8240d9f4d17155b..e415aa36f41c9a6cccc5f2729c5165bd3addb165 100644 (file)
@@ -4652,3 +4652,36 @@ PLyUnicode_FromString(const char *s)
 }
 
 #endif   /* PY_MAJOR_VERSION >= 3 */
+
+#if PY_MAJOR_VERSION < 3
+
+/* Define aliases plpython2_call_handler etc */
+Datum          plpython2_call_handler(PG_FUNCTION_ARGS);
+Datum          plpython2_inline_handler(PG_FUNCTION_ARGS);
+Datum          plpython2_validator(PG_FUNCTION_ARGS);
+
+PG_FUNCTION_INFO_V1(plpython2_call_handler);
+
+Datum
+plpython2_call_handler(PG_FUNCTION_ARGS)
+{
+       return plpython_call_handler(fcinfo);
+}
+
+PG_FUNCTION_INFO_V1(plpython2_inline_handler);
+
+Datum
+plpython2_inline_handler(PG_FUNCTION_ARGS)
+{
+       return plpython_inline_handler(fcinfo);
+}
+
+PG_FUNCTION_INFO_V1(plpython2_validator);
+
+Datum
+plpython2_validator(PG_FUNCTION_ARGS)
+{
+       return plpython_validator(fcinfo);
+}
+
+#endif   /* PY_MAJOR_VERSION < 3 */
diff --git a/src/pl/plpython/plpython2u--1.0.sql b/src/pl/plpython/plpython2u--1.0.sql
new file mode 100644 (file)
index 0000000..0e47876
--- /dev/null
@@ -0,0 +1,9 @@
+/* src/pl/plpython/plpython2u--1.0.sql */
+
+/*
+ * Currently, all the interesting stuff is done by CREATE LANGUAGE.
+ * Later we will probably "dumb down" that command and put more of the
+ * knowledge into this script.
+ */
+
+CREATE PROCEDURAL LANGUAGE plpython2u;
diff --git a/src/pl/plpython/plpython2u--unpackaged--1.0.sql b/src/pl/plpython/plpython2u--unpackaged--1.0.sql
new file mode 100644 (file)
index 0000000..a89d8b4
--- /dev/null
@@ -0,0 +1,7 @@
+/* src/pl/plpython/plpython2u--unpackaged--1.0.sql */
+
+ALTER EXTENSION plpython2u ADD PROCEDURAL LANGUAGE plpython2u;
+-- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to.
+ALTER EXTENSION plpython2u ADD FUNCTION plpython2_call_handler();
+ALTER EXTENSION plpython2u ADD FUNCTION plpython2_inline_handler(internal);
+ALTER EXTENSION plpython2u ADD FUNCTION plpython2_validator(oid);
diff --git a/src/pl/plpython/plpython2u.control b/src/pl/plpython/plpython2u.control
new file mode 100644 (file)
index 0000000..39c2b79
--- /dev/null
@@ -0,0 +1,7 @@
+# plpython2u extension
+comment = 'PL/Python2U untrusted procedural language'
+default_version = '1.0'
+module_pathname = '$libdir/plpython2'
+relocatable = false
+schema = pg_catalog
+superuser = true
diff --git a/src/pl/plpython/plpython3u--1.0.sql b/src/pl/plpython/plpython3u--1.0.sql
new file mode 100644 (file)
index 0000000..d5c6e5a
--- /dev/null
@@ -0,0 +1,9 @@
+/* src/pl/plpython/plpython3u--1.0.sql */
+
+/*
+ * Currently, all the interesting stuff is done by CREATE LANGUAGE.
+ * Later we will probably "dumb down" that command and put more of the
+ * knowledge into this script.
+ */
+
+CREATE PROCEDURAL LANGUAGE plpython3u;
diff --git a/src/pl/plpython/plpython3u--unpackaged--1.0.sql b/src/pl/plpython/plpython3u--unpackaged--1.0.sql
new file mode 100644 (file)
index 0000000..b1c0d03
--- /dev/null
@@ -0,0 +1,7 @@
+/* src/pl/plpython/plpython3u--unpackaged--1.0.sql */
+
+ALTER EXTENSION plpython3u ADD PROCEDURAL LANGUAGE plpython3u;
+-- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to.
+ALTER EXTENSION plpython3u ADD FUNCTION plpython3_call_handler();
+ALTER EXTENSION plpython3u ADD FUNCTION plpython3_inline_handler(internal);
+ALTER EXTENSION plpython3u ADD FUNCTION plpython3_validator(oid);
diff --git a/src/pl/plpython/plpython3u.control b/src/pl/plpython/plpython3u.control
new file mode 100644 (file)
index 0000000..01905ef
--- /dev/null
@@ -0,0 +1,7 @@
+# plpython3u extension
+comment = 'PL/Python3U untrusted procedural language'
+default_version = '1.0'
+module_pathname = '$libdir/plpython3'
+relocatable = false
+schema = pg_catalog
+superuser = true
diff --git a/src/pl/plpython/plpythonu--1.0.sql b/src/pl/plpython/plpythonu--1.0.sql
new file mode 100644 (file)
index 0000000..beb0aa1
--- /dev/null
@@ -0,0 +1,9 @@
+/* src/pl/plpython/plpythonu--1.0.sql */
+
+/*
+ * Currently, all the interesting stuff is done by CREATE LANGUAGE.
+ * Later we will probably "dumb down" that command and put more of the
+ * knowledge into this script.
+ */
+
+CREATE PROCEDURAL LANGUAGE plpythonu;
diff --git a/src/pl/plpython/plpythonu--unpackaged--1.0.sql b/src/pl/plpython/plpythonu--unpackaged--1.0.sql
new file mode 100644 (file)
index 0000000..7926233
--- /dev/null
@@ -0,0 +1,7 @@
+/* src/pl/plpython/plpythonu--unpackaged--1.0.sql */
+
+ALTER EXTENSION plpythonu ADD PROCEDURAL LANGUAGE plpythonu;
+-- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to.
+ALTER EXTENSION plpythonu ADD FUNCTION plpython_call_handler();
+ALTER EXTENSION plpythonu ADD FUNCTION plpython_inline_handler(internal);
+ALTER EXTENSION plpythonu ADD FUNCTION plpython_validator(oid);
diff --git a/src/pl/plpython/plpythonu.control b/src/pl/plpython/plpythonu.control
new file mode 100644 (file)
index 0000000..ae91b1c
--- /dev/null
@@ -0,0 +1,7 @@
+# plpythonu extension
+comment = 'PL/PythonU untrusted procedural language'
+default_version = '1.0'
+module_pathname = '$libdir/plpython2'
+relocatable = false
+schema = pg_catalog
+superuser = true
index 319d5e0925d1a405a15aefe980909c7ba9f6245c..72d5d657ec3f593f8b92028116dea70e270a548d 100644 (file)
@@ -3,4 +3,6 @@
 --
 SET client_min_messages = WARNING;
 
-DROP PROCEDURAL LANGUAGE plpythonu CASCADE;
+DROP EXTENSION plpythonu CASCADE;
+
+DROP EXTENSION IF EXISTS plpython2u CASCADE;
index 915189847a7cf0fd420da6c6c942dec65e60abbf..c8d5ef5f534613320f857863ade9d39cdb7287e1 100644 (file)
@@ -1,5 +1,5 @@
 -- first some tests of basic functionality
-CREATE LANGUAGE plpython2u;
+CREATE EXTENSION plpython2u;
 
 -- really stupid function just to get the module loaded
 CREATE FUNCTION stupid() RETURNS text AS 'return "zarkon"' LANGUAGE plpythonu;
index b29478dd6fd135d4b1803bffe1da29d3dc546f0d..c7797c61f5eca6e6fe020831c98fa7e88c8834d9 100644 (file)
@@ -1,6 +1,6 @@
 #-------------------------------------------------------------------------
 #
-# Makefile for the pltcl shared object
+# Makefile for the pl/tcl procedural language
 #
 # src/pl/tcl/Makefile
 #
@@ -35,9 +35,13 @@ SHLIB_LINK += $(TCL_LIBS) -lc
 endif
 
 NAME = pltcl
+
 OBJS = pltcl.o
 
-REGRESS_OPTS = --dbname=$(PL_TESTDB) --load-language=pltcl
+DATA = pltcl.control pltcl--1.0.sql pltcl--unpackaged--1.0.sql \
+       pltclu.control pltclu--1.0.sql pltclu--unpackaged--1.0.sql
+
+REGRESS_OPTS = --dbname=$(PL_TESTDB) --load-extension=pltcl
 REGRESS = pltcl_setup pltcl_queries
 # where to find psql for running the tests
 PSQLDIR = $(bindir)
@@ -49,15 +53,29 @@ ifeq ($(TCL_SHARED_BUILD), 1)
 all: all-lib
        $(MAKE) -C modules $@
 
-install: all installdirs install-lib
+
+install: all installdirs install-lib install-data
        $(MAKE) -C modules $@
 
 installdirs: installdirs-lib
+       $(MKDIR_P) '$(DESTDIR)$(datadir)/extension'
        $(MAKE) -C modules $@
 
-uninstall: uninstall-lib
+uninstall: uninstall-lib uninstall-data
        $(MAKE) -C modules $@
 
+install-data:
+       @for file in $(addprefix $(srcdir)/, $(DATA)); do \
+         echo "$(INSTALL_DATA) $$file '$(DESTDIR)$(datadir)/extension'"; \
+         $(INSTALL_DATA) $$file '$(DESTDIR)$(datadir)/extension'; \
+       done
+
+uninstall-data:
+       rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA)))
+
+.PHONY: install-data uninstall-data
+
+
 check: submake
        $(pg_regress_check) $(REGRESS_OPTS) $(REGRESS)
 
diff --git a/src/pl/tcl/pltcl--1.0.sql b/src/pl/tcl/pltcl--1.0.sql
new file mode 100644 (file)
index 0000000..897e1a1
--- /dev/null
@@ -0,0 +1,9 @@
+/* src/pl/tcl/pltcl--1.0.sql */
+
+/*
+ * Currently, all the interesting stuff is done by CREATE LANGUAGE.
+ * Later we will probably "dumb down" that command and put more of the
+ * knowledge into this script.
+ */
+
+CREATE PROCEDURAL LANGUAGE pltcl;
diff --git a/src/pl/tcl/pltcl--unpackaged--1.0.sql b/src/pl/tcl/pltcl--unpackaged--1.0.sql
new file mode 100644 (file)
index 0000000..dfad66c
--- /dev/null
@@ -0,0 +1,5 @@
+/* src/pl/tcl/pltcl--unpackaged--1.0.sql */
+
+ALTER EXTENSION pltcl ADD PROCEDURAL LANGUAGE pltcl;
+-- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to.
+ALTER EXTENSION pltcl ADD FUNCTION pltcl_call_handler();
diff --git a/src/pl/tcl/pltcl.control b/src/pl/tcl/pltcl.control
new file mode 100644 (file)
index 0000000..b9dc1b8
--- /dev/null
@@ -0,0 +1,7 @@
+# pltcl extension
+comment = 'PL/Tcl procedural language'
+default_version = '1.0'
+module_pathname = '$libdir/pltcl'
+relocatable = false
+schema = pg_catalog
+superuser = false
diff --git a/src/pl/tcl/pltclu--1.0.sql b/src/pl/tcl/pltclu--1.0.sql
new file mode 100644 (file)
index 0000000..e53bb04
--- /dev/null
@@ -0,0 +1,9 @@
+/* src/pl/tcl/pltclu--1.0.sql */
+
+/*
+ * Currently, all the interesting stuff is done by CREATE LANGUAGE.
+ * Later we will probably "dumb down" that command and put more of the
+ * knowledge into this script.
+ */
+
+CREATE PROCEDURAL LANGUAGE pltclu;
diff --git a/src/pl/tcl/pltclu--unpackaged--1.0.sql b/src/pl/tcl/pltclu--unpackaged--1.0.sql
new file mode 100644 (file)
index 0000000..a5d359f
--- /dev/null
@@ -0,0 +1,5 @@
+/* src/pl/tcl/pltclu--unpackaged--1.0.sql */
+
+ALTER EXTENSION pltclu ADD PROCEDURAL LANGUAGE pltclu;
+-- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to.
+ALTER EXTENSION pltclu ADD FUNCTION pltclu_call_handler();
diff --git a/src/pl/tcl/pltclu.control b/src/pl/tcl/pltclu.control
new file mode 100644 (file)
index 0000000..1418dc5
--- /dev/null
@@ -0,0 +1,7 @@
+# pltclu extension
+comment = 'PL/TclU untrusted procedural language'
+default_version = '1.0'
+module_pathname = '$libdir/pltcl'
+relocatable = false
+schema = pg_catalog
+superuser = true
index a6160298efb4590708085c8c7347b3033fcb08d0..6ecf78488e01943b912f4d4838f28dac11e2a776 100644 (file)
@@ -86,6 +86,7 @@ char     *outputdir = ".";
 char      *psqldir = PGBINDIR;
 char      *launcher = NULL;
 static _stringlist *loadlanguage = NULL;
+static _stringlist *loadextension = NULL;
 static int     max_connections = 0;
 static char *encoding = NULL;
 static _stringlist *schedulelist = NULL;
@@ -1800,6 +1801,16 @@ create_database(const char *dbname)
                header(_("installing %s"), sl->str);
                psql_command(dbname, "CREATE OR REPLACE LANGUAGE \"%s\"", sl->str);
        }
+
+       /*
+        * Install any requested extensions.  We use CREATE IF NOT EXISTS
+        * so that this will work whether or not the extension is preinstalled.
+        */
+       for (sl = loadextension; sl != NULL; sl = sl->next)
+       {
+               header(_("installing %s"), sl->str);
+               psql_command(dbname, "CREATE EXTENSION IF NOT EXISTS \"%s\"", sl->str);
+       }
 }
 
 static void
@@ -1862,6 +1873,8 @@ help(void)
        printf(_("  --inputdir=DIR            take input files from DIR (default \".\")\n"));
        printf(_("  --load-language=lang      load the named language before running the\n"));
        printf(_("                            tests; can appear multiple times\n"));
+       printf(_("  --load-extension=ext      load the named extension before running the\n"));
+       printf(_("                            tests; can appear multiple times\n"));
        printf(_("  --create-role=ROLE        create the specified role before testing\n"));
        printf(_("  --max-connections=N       maximum number of concurrent connections\n"));
        printf(_("                            (default is 0 meaning unlimited)\n"));
@@ -1925,6 +1938,7 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc
                {"temp-config", required_argument, NULL, 19},
                {"use-existing", no_argument, NULL, 20},
                {"launcher", required_argument, NULL, 21},
+               {"load-extension", required_argument, NULL, 22},
                {NULL, 0, NULL, 0}
        };
 
@@ -2021,6 +2035,9 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc
                        case 21:
                                launcher = strdup(optarg);
                                break;
+                       case 22:
+                               add_stringlist_item(&loadextension, optarg);
+                               break;
                        default:
                                /* getopt_long already emitted a complaint */
                                fprintf(stderr, _("\nTry \"%s -h\" for more information.\n"),
index f3024f26ca67ce5597f94bd0dfc6c62ded8c87f6..2fe6b8a05bec82a2464ba3e83ce263170a40f17e 100644 (file)
@@ -146,14 +146,14 @@ sub plcheck
         my $lang = $pl eq 'tcl' ? 'pltcl' : $pl;
         next unless -d "../../$Config/$lang";
         $lang = 'plpythonu' if $lang eq 'plpython';
-        my @lang_args = ("--load-language=$lang");
+        my @lang_args = ("--load-extension=$lang");
         chdir $pl;
         my @tests = fetchTests();
         if ($lang eq 'plperl')
         {
 
             # run both trusted and untrusted perl tests
-            push(@lang_args, "--load-language=plperlu");
+            push(@lang_args, "--load-extension=plperlu");
 
             # assume we're using this perl to built postgres
             # test if we can run two interpreters in one backend, and if so