Create extension infrastructure for the core procedural languages.

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).
This commit is contained in:
Tom Lane 2011-03-04 21:51:14 -05:00
parent efa415da8c
commit 63b656b7bf
41 changed files with 399 additions and 43 deletions

View 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

View 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;

View 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));
}

View File

@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201103041
#define CATALOG_VERSION_NO 201103042
#endif

View 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 */

View 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)

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View 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: 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
# Force these dependencies to be known even without dependency info built:

View File

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

View File

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

View File

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

View 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

View 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;

View 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();

View 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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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;

View 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;

View 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)

View File

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

View File

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

7
src/pl/tcl/pltcl.control Normal file
View File

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

View File

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

View File

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

View File

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

View 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"),

View 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