aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/Makefile3
-rw-r--r--src/bin/pg_dump/pg_dump.c2
-rw-r--r--src/bin/pg_dump/t/001_basic.pl42
-rw-r--r--src/bin/pg_dump/t/002_pg_dump.pl2859
-rw-r--r--src/test/modules/Makefile1
-rw-r--r--src/test/modules/test_pg_dump/.gitignore4
-rw-r--r--src/test/modules/test_pg_dump/Makefile25
-rw-r--r--src/test/modules/test_pg_dump/README2
-rw-r--r--src/test/modules/test_pg_dump/expected/test_pg_dump.out6
-rw-r--r--src/test/modules/test_pg_dump/sql/test_pg_dump.sql1
-rw-r--r--src/test/modules/test_pg_dump/t/001_base.pl535
-rw-r--r--src/test/modules/test_pg_dump/test_pg_dump--1.0.sql15
-rw-r--r--src/test/modules/test_pg_dump/test_pg_dump.control3
13 files changed, 3497 insertions, 1 deletions
diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile
index 95967893d82..260804b5a7e 100644
--- a/src/bin/pg_dump/Makefile
+++ b/src/bin/pg_dump/Makefile
@@ -42,6 +42,9 @@ install: all installdirs
installdirs:
$(MKDIR_P) '$(DESTDIR)$(bindir)'
+check:
+ $(prove_check)
+
uninstall:
rm -f $(addprefix '$(DESTDIR)$(bindir)'/, pg_dump$(X) pg_restore$(X) pg_dumpall$(X))
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 6e2610fa3ff..1267afbce9a 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -1564,7 +1564,7 @@ selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
* those changes preserved.
*/
if (dopt->binary_upgrade && extinfo->dobj.catId.oid < (Oid) FirstNormalObjectId)
- extinfo->dobj.dump = DUMP_COMPONENT_ACL;
+ extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
else
extinfo->dobj.dump = extinfo->dobj.dump_contains =
dopt->include_everything ? DUMP_COMPONENT_ALL :
diff --git a/src/bin/pg_dump/t/001_basic.pl b/src/bin/pg_dump/t/001_basic.pl
new file mode 100644
index 00000000000..1411ef7a271
--- /dev/null
+++ b/src/bin/pg_dump/t/001_basic.pl
@@ -0,0 +1,42 @@
+use strict;
+use warnings;
+
+use Config;
+use PostgresNode;
+use TestLib;
+use Test::More tests => 15;
+
+my $tempdir = TestLib::tempdir;
+my $tempdir_short = TestLib::tempdir_short;
+
+#########################################
+# Basic checks
+
+program_help_ok('pg_dump');
+program_version_ok('pg_dump');
+program_options_handling_ok('pg_dump');
+
+#########################################
+# Test various invalid options and disallowed combinations
+# Doesn't require a PG instance to be set up, so do this first.
+
+command_exit_is([ 'pg_dump', 'qqq', 'abc' ],
+ 1, 'pg_dump: too many command-line arguments (first is "asd")');
+
+command_exit_is([ 'pg_dump', '-s', '-a' ],
+ 1, 'pg_dump: options -s/--schema-only and -a/--data-only cannot be used together');
+
+command_exit_is([ 'pg_dump', '-c', '-a' ],
+ 1, 'pg_dump: options -c/--clean and -a/--data-only cannot be used together');
+
+command_exit_is([ 'pg_dump', '--inserts', '-o' ],
+ 1, 'pg_dump: options --inserts/--column-inserts and -o/--oids cannot be used together');
+
+command_exit_is([ 'pg_dump', '--if-exists' ],
+ 1, 'pg_dump: option --if-exists requires option -c/--clean');
+
+command_exit_is([ 'pg_dump', '-j' ],
+ 1, 'pg_dump: option requires an argument -- \'j\'');
+
+command_exit_is([ 'pg_dump', '-j3' ],
+ 1, 'pg_dump: parallel backup only supported by the directory format');
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
new file mode 100644
index 00000000000..4270042250b
--- /dev/null
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -0,0 +1,2859 @@
+use strict;
+use warnings;
+
+use Config;
+use PostgresNode;
+use TestLib;
+use Test::More;
+
+my $tempdir = TestLib::tempdir;
+my $tempdir_short = TestLib::tempdir_short;
+
+###############################################################
+# Definition of the pg_dump runs to make.
+#
+# Each of these runs are named and those names are used below
+# to define how each test should (or shouldn't) treat a result
+# from a given run.
+#
+# test_key indicates that a given run should simply use the same
+# set of like/unlike tests as another run, and which run that is.
+#
+# dump_cmd is the pg_dump command to run, which is an array of
+# the full command and arguments to run. Note that this is run
+# using $node->command_ok(), so the port does not need to be
+# specified and is pulled from $PGPORT, which is set by the
+# PostgresNode system.
+#
+# restore_cmd is the pg_restore command to run, if any. Note
+# that this should generally be used when the pg_dump goes to
+# a non-text file and that the restore can then be used to
+# generate a text file to run through the tests from the
+# non-text file generated by pg_dump.
+#
+# TODO: Have pg_restore actually restore to an independent
+# database and then pg_dump *that* database (or something along
+# those lines) to validate that part of the process.
+
+my %pgdump_runs = (
+ binary_upgrade => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/binary_upgrade.sql",
+ '--schema-only',
+ '--binary-upgrade',
+ '-d', 'postgres', # alternative way to specify database
+ ],
+ },
+ clean => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/clean.sql",
+ '-c',
+ '-d', 'postgres', # alternative way to specify database
+ ],
+ },
+ clean_if_exists => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/clean_if_exists.sql",
+ '-c',
+ '--if-exists',
+ '-E', 'UTF8', # no-op, just tests that option is accepted
+ 'postgres',
+ ],
+ },
+ column_inserts => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/column_inserts.sql",
+ '-a',
+ '--column-inserts',
+ 'postgres',
+ ],
+ },
+ createdb => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/createdb.sql",
+ '-C',
+ '-R', # no-op, just for testing
+ 'postgres',
+ ],
+ },
+ data_only => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/data_only.sql",
+ '-a',
+ '-v', # no-op, just make sure it works
+ 'postgres',
+ ],
+ },
+ defaults => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/defaults.sql",
+ 'postgres',
+ ],
+ },
+ defaults_custom_format => {
+ test_key => 'defaults',
+ dump_cmd => [
+ 'pg_dump',
+ '-Fc',
+ '-Z6',
+ '-f', "$tempdir/defaults_custom_format.dump",
+ 'postgres',
+ ],
+ restore_cmd => [
+ 'pg_restore',
+ '-f', "$tempdir/defaults_custom_format.sql",
+ "$tempdir/defaults_custom_format.dump",
+ ],
+ },
+ defaults_dir_format => {
+ test_key => 'defaults',
+ dump_cmd => [
+ 'pg_dump',
+ '-Fd',
+ '-f', "$tempdir/defaults_dir_format",
+ 'postgres',
+ ],
+ restore_cmd => [
+ 'pg_restore',
+ '-f', "$tempdir/defaults_dir_format.sql",
+ "$tempdir/defaults_dir_format",
+ ],
+ },
+ defaults_parallel => {
+ test_key => 'defaults',
+ dump_cmd => [
+ 'pg_dump',
+ '-Fd',
+ '-j2',
+ '-f', "$tempdir/defaults_parallel",
+ 'postgres',
+ ],
+ restore_cmd => [
+ 'pg_restore',
+ '-f', "$tempdir/defaults_parallel.sql",
+ "$tempdir/defaults_parallel",
+ ],
+ },
+ defaults_tar_format => {
+ test_key => 'defaults',
+ dump_cmd => [
+ 'pg_dump',
+ '-Ft',
+ '-f', "$tempdir/defaults_tar_format.tar",
+ 'postgres',
+ ],
+ restore_cmd => [
+ 'pg_restore',
+ '-f', "$tempdir/defaults_tar_format.sql",
+ "$tempdir/defaults_tar_format.tar",
+ ],
+ },
+ exclude_dump_test_schema => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/exclude_dump_test_schema.sql",
+ '-N', 'dump_test',
+ 'postgres',
+ ],
+ },
+ exclude_test_table => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/exclude_test_table.sql",
+ '-T', 'dump_test.test_table',
+ 'postgres',
+ ],
+ },
+ exclude_test_table_data => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/exclude_test_table_data.sql",
+ '--exclude-table-data=dump_test.test_table',
+ 'postgres',
+ ],
+ },
+ pg_dumpall_globals => {
+ dump_cmd => [
+ 'pg_dumpall',
+ '-f', "$tempdir/pg_dumpall_globals.sql",
+ '-g',
+ ],
+ },
+ no_privs => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/no_privs.sql",
+ '-x',
+ 'postgres',
+ ],
+ },
+ no_owner => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/no_owner.sql",
+ '-O',
+ 'postgres',
+ ],
+ },
+ only_dump_test_schema => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/only_dump_test_schema.sql",
+ '-n', 'dump_test',
+ 'postgres',
+ ],
+ },
+ only_dump_test_table => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/only_dump_test_table.sql",
+ '-t', 'dump_test.test_table',
+ '--lock-wait-timeout=1000000',
+ 'postgres',
+ ],
+ },
+ role => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/role.sql",
+ '--role=dump_test',
+ '--schema=dump_test_second_schema',
+ 'postgres',
+ ],
+ },
+ schema_only => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/schema_only.sql",
+ '-s',
+ 'postgres',
+ ],
+ },
+ section_pre_data => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/section_pre_data.sql",
+ '--section=pre-data',
+ 'postgres',
+ ],
+ },
+ section_data => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/section_data.sql",
+ '--section=data',
+ 'postgres',
+ ],
+ },
+ section_post_data => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/section_post_data.sql",
+ '--section=post-data',
+ 'postgres',
+ ],
+ },
+ test_schema_plus_blobs => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/test_schema_plus_blobs.sql",
+ '-n', 'dump_test',
+ '-b',
+ 'postgres',
+ ],
+ },
+);
+
+###############################################################
+# Definition of the tests to run.
+#
+# Each test is defined using the log message that will be used.
+#
+# A regexp should be defined for each test which provides the
+# basis for the test. That regexp will be run against the output
+# file of each of the runs which the test is to be run against
+# and the success of the result will depend on if the regexp
+# result matches the expected 'like' or 'unlike' case.
+#
+# For each test, there are two sets of runs defined, one for
+# the 'like' tests and one for the 'unlike' tests. 'like'
+# essentially means "the regexp for this test must match the
+# output file". 'unlike' is the opposite.
+#
+# There are a few 'catch-all' tests which can be used to have
+# a single, simple, test to over a range of other tests. For
+# example, there is a '^CREATE ' test, which is used for the
+# 'data-only' test as there should never be any kind of CREATE
+# statement in a 'data-only' run. Without the catch-all, we
+# would have to list the 'data-only' run in each and every
+# 'CREATE xxxx' test, which would be a lot of additional tests.
+#
+# Note that it makes no sense for the same run to ever be listed
+# in both 'like' and 'unlike' categories.
+#
+# There can then be a 'create_sql' and 'create_order' for a
+# given test. The 'create_sql' commands are collected up in
+# 'create_order' and then run against the database prior to any
+# of the pg_dump runs happening. This is what "seeds" the
+# system with objects to be dumped out.
+#
+# Building of this hash takes a bit of time as all of the regexps
+# included in it are compiled. This greatly improves performance
+# as the regexps are used for each run the test applies to.
+
+my %tests = (
+ 'ALTER DEFAULT PRIVILEGES FOR ROLE dump_test' => {
+ create_order => 14,
+ create_sql => 'ALTER DEFAULT PRIVILEGES
+ FOR ROLE dump_test IN SCHEMA dump_test
+ GRANT SELECT ON TABLES TO dump_test;',
+ regexp => qr/^
+ \QALTER DEFAULT PRIVILEGES \E
+ \QFOR ROLE dump_test IN SCHEMA dump_test \E
+ \QGRANT SELECT ON TABLES TO dump_test;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ no_privs => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_pre_data => 1,
+ section_data => 1,
+ },
+ },
+ 'ALTER ROLE dump_test' => {
+ regexp => qr/^
+ \QALTER ROLE dump_test WITH \E
+ \QNOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOLOGIN \E
+ \QNOREPLICATION NOBYPASSRLS;\E
+ $/xm,
+ like => {
+ pg_dumpall_globals => 1,
+ },
+ unlike => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'ALTER FUNCTION dump_test.pltestlang_call_handler() OWNER TO' => {
+ regexp => qr/^
+ \QALTER FUNCTION dump_test.pltestlang_call_handler() \E
+ \QOWNER TO \E
+ .*;$/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ },
+ },
+ 'ALTER PROCEDURAL LANGUAGE pltestlang OWNER TO' => {
+ regexp => qr/^ALTER PROCEDURAL LANGUAGE pltestlang OWNER TO .*;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'ALTER SCHEMA dump_test OWNER TO' => {
+ regexp => qr/^ALTER SCHEMA dump_test OWNER TO .*;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ },
+ },
+ 'ALTER SCHEMA dump_test_second_schema OWNER TO' => {
+ regexp => qr/^ALTER SCHEMA dump_test_second_schema OWNER TO .*;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'ALTER TABLE ONLY test_table ADD CONSTRAINT ... PRIMARY KEY' => {
+ regexp => qr/^
+ \QALTER TABLE ONLY test_table\E \n^\s+
+ \QADD CONSTRAINT test_table_pkey PRIMARY KEY (col1);\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_pre_data => 1,
+ section_data => 1,
+ },
+ },
+ 'ALTER TABLE test_table OWNER TO' => {
+ regexp => qr/^ALTER TABLE test_table OWNER TO .*;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ },
+ },
+ 'ALTER TABLE test_table ENABLE ROW LEVEL SECURITY' => {
+ create_order => 23,
+ create_sql => 'ALTER TABLE dump_test.test_table
+ ENABLE ROW LEVEL SECURITY;',
+ regexp => qr/^ALTER TABLE test_table ENABLE ROW LEVEL SECURITY;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ section_pre_data => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ },
+ },
+ 'ALTER TABLE test_second_table OWNER TO' => {
+ regexp => qr/^ALTER TABLE test_second_table OWNER TO .*;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ },
+ },
+ 'ALTER TABLE test_third_table OWNER TO' => {
+ regexp => qr/^ALTER TABLE test_third_table OWNER TO .*;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ # catch-all for ALTER ... OWNER (except LARGE OBJECTs)
+ 'ALTER ... OWNER commands (except LARGE OBJECTs)' => {
+ regexp => qr/^ALTER (?!LARGE OBJECT)(.*) OWNER TO .*;$/m,
+ like => { }, # use more-specific options above
+ unlike => {
+ column_inserts => 1,
+ data_only => 1,
+ section_data => 1,
+ },
+ },
+ # catch-all for ALTER ... OWNER
+ 'ALTER ... OWNER commands' => {
+ regexp => qr/^ALTER .* OWNER TO .*;$/m,
+ like => { }, # use more-specific options above
+ unlike => {
+ no_owner => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'BLOB load (contents are of test_table)' => {
+ create_order => 14,
+ create_sql =>
+ "\\o '$tempdir/large_object_test.sql'\n"
+ . "table dump_test.test_table;\n"
+ . "\\o\n"
+ . "\\lo_import '$tempdir/large_object_test.sql'\n",
+ regexp => qr/^
+ \QSELECT pg_catalog.lo_open\E \('\d+',\ \d+\);\n
+ \QSELECT pg_catalog.lowrite(0, \E
+ \Q'\x310a320a330a340a350a360a370a380a390a');\E\n
+ \QSELECT pg_catalog.lo_close(0);\E
+ $/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ section_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ binary_upgrade => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ },
+ },
+ 'COMMENT ON DATABASE postgres' => {
+ regexp => qr/^COMMENT ON DATABASE postgres IS .*;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ },
+ },
+ 'COMMENT ON EXTENSION plpgsql' => {
+ regexp => qr/^COMMENT ON EXTENSION plpgsql IS .*;$/m,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ binary_upgrade => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ },
+ },
+ 'COMMENT ON TABLE dump_test.test_table' => {
+ create_order => 36,
+ create_sql => 'COMMENT ON TABLE dump_test.test_table
+ IS \'comment on table\';',
+ regexp => qr/^COMMENT ON TABLE test_table IS 'comment on table';$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ },
+ },
+ 'COMMENT ON COLUMN dump_test.test_table.col1' => {
+ create_order => 36,
+ create_sql => 'COMMENT ON COLUMN dump_test.test_table.col1
+ IS \'comment on column\';',
+ regexp => qr/^
+ \QCOMMENT ON COLUMN test_table.col1 IS 'comment on column';\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ },
+ },
+ 'COMMENT ON COLUMN dump_test.composite.f1' => {
+ create_order => 44,
+ create_sql => 'COMMENT ON COLUMN dump_test.composite.f1
+ IS \'comment on column of type\';',
+ regexp => qr/^
+ \QCOMMENT ON COLUMN composite.f1 IS 'comment on column of type';\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ },
+ },
+ # catch-all for COMMENTs
+ 'COMMENT commands' => {
+ regexp => qr/^COMMENT ON /m,
+ like => { }, # use more-specific options above
+ unlike => {
+ column_inserts => 1,
+ data_only => 1,
+ pg_dumpall_globals => 1,
+ section_data => 1,
+ section_post_data => 1,
+ },
+ },
+ 'COPY test_table' => {
+ create_order => 4,
+ create_sql =>
+ 'INSERT INTO dump_test.test_table (col1) '
+ . 'SELECT generate_series FROM generate_series(1,9);',
+ regexp => qr/^
+ \QCOPY test_table (col1) FROM stdin;\E
+ \n(?:\d\n){9}\\\.\n
+ $/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ data_only => 1,
+ defaults => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ section_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ },
+ },
+ 'COPY fk_reference_test_table' => {
+ create_order => 22,
+ create_sql =>
+ 'INSERT INTO dump_test.fk_reference_test_table (col1) '
+ . 'SELECT generate_series FROM generate_series(1,5);',
+ regexp => qr/^
+ \QCOPY fk_reference_test_table (col1) FROM stdin;\E
+ \n(?:\d\n){5}\\\.\n
+ $/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ data_only => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ section_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ },
+ },
+ 'COPY fk_reference_test_table second' => {
+ regexp => qr/^
+ \QCOPY test_table (col1) FROM stdin;\E
+ \n(?:\d\n){9}\\\.\n.*
+ \QCOPY fk_reference_test_table (col1) FROM stdin;\E
+ \n(?:\d\n){5}\\\.\n
+ $/xms,
+ like => {
+ data_only => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ },
+ },
+ 'COPY test_second_table' => {
+ create_order => 7,
+ create_sql =>
+ 'INSERT INTO dump_test.test_second_table (col1, col2) '
+ . 'SELECT generate_series, generate_series::text '
+ . 'FROM generate_series(1,9);',
+ regexp => qr/^
+ \QCOPY test_second_table (col1, col2) FROM stdin;\E
+ \n(?:\d\t\d\n){9}\\\.\n
+ $/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ data_only => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ section_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ },
+ },
+ 'COPY test_third_table' => {
+ create_order => 12,
+ create_sql =>
+ 'INSERT INTO dump_test_second_schema.test_third_table (col1) '
+ . 'SELECT generate_series FROM generate_series(1,9);',
+ regexp => qr/^
+ \QCOPY test_third_table (col1) FROM stdin;\E
+ \n(?:\d\n){9}\\\.\n
+ $/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ data_only => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ section_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'INSERT INTO test_table' => {
+ regexp => qr/^
+ (?:INSERT\ INTO\ test_table\ \(col1\)\ VALUES\ \(\d\);\n){9}
+ $/xm,
+ like => {
+ column_inserts => 1,
+ },
+ unlike => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ data_only => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ section_data => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'INSERT INTO test_second_table' => {
+ regexp => qr/^
+ (?:INSERT\ INTO\ test_second_table\ \(col1,\ col2\)
+ \ VALUES\ \(\d,\ '\d'\);\n){9}$/xm,
+ like => {
+ column_inserts => 1,
+ },
+ unlike => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ data_only => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ section_data => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'INSERT INTO test_third_table' => {
+ regexp => qr/^
+ (?:INSERT\ INTO\ test_third_table\ \(col1\)
+ \ VALUES\ \(\d\);\n){9}$/xm,
+ like => {
+ column_inserts => 1,
+ },
+ unlike => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ data_only => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ section_data => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'COPY ... commands' => { # catch-all for COPY
+ regexp => qr/^COPY /m,
+ like => { }, # use more-specific options above
+ unlike => {
+ binary_upgrade => 1,
+ column_inserts => 1,
+ pg_dumpall_globals => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE ROLE dump_test' => {
+ create_order => 1,
+ create_sql => 'CREATE ROLE dump_test;',
+ regexp => qr/^CREATE ROLE dump_test;$/m,
+ like => {
+ pg_dumpall_globals => 1,
+ },
+ unlike => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'CREATE DATABASE postgres' => {
+ regexp => qr/^
+ \QCREATE DATABASE postgres WITH TEMPLATE = template0 \E
+ .*;$/xm,
+ like => {
+ createdb => 1,
+ },
+ unlike => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'CREATE EXTENSION ... plpgsql' => {
+ regexp => qr/^
+ \QCREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;\E
+ $/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ binary_upgrade => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'CREATE AGGREGATE dump_test.newavg' => {
+ create_order => 25,
+ create_sql => 'CREATE AGGREGATE dump_test.newavg (
+ sfunc = int4_avg_accum,
+ basetype = int4,
+ stype = _int8,
+ finalfunc = int8_avg,
+ initcond1 = \'{0,0}\'
+ );',
+ regexp => qr/^
+ \QCREATE AGGREGATE newavg(integer) (\E
+ \n\s+\QSFUNC = int4_avg_accum,\E
+ \n\s+\QSTYPE = bigint[],\E
+ \n\s+\QINITCOND = '{0,0}',\E
+ \n\s+\QFINALFUNC = int8_avg\E
+ \n\);$/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE DOMAIN dump_test.us_postal_code' => {
+ create_order => 29,
+ create_sql => 'CREATE DOMAIN dump_test.us_postal_code AS TEXT
+ CHECK(VALUE ~ \'^\d{5}$\' OR
+ VALUE ~ \'^\d{5}-\d{4}$\');',
+ regexp => qr/^
+ \QCREATE DOMAIN us_postal_code AS text\E
+ \n\s+
+ \QCONSTRAINT us_postal_code_check CHECK \E
+ \Q(((VALUE ~ '^\d{5}\E
+ \$\Q'::text) OR (VALUE ~ '^\d{5}-\d{4}\E\$
+ \Q'::text)));\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE FUNCTION dump_test.pltestlang_call_handler' => {
+ create_order => 17,
+ create_sql => 'CREATE FUNCTION dump_test.pltestlang_call_handler()
+ RETURNS LANGUAGE_HANDLER AS \'$libdir/plpgsql\',
+ \'plpgsql_call_handler\' LANGUAGE C;',
+ regexp => qr/^
+ \QCREATE FUNCTION pltestlang_call_handler() \E
+ \QRETURNS language_handler\E
+ \n\s+\QLANGUAGE c\E
+ \n\s+AS\ \'\$
+ \Qlibdir\/plpgsql', 'plpgsql_call_handler';\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE FUNCTION dump_test.trigger_func' => {
+ create_order => 30,
+ create_sql => 'CREATE FUNCTION dump_test.trigger_func()
+ RETURNS trigger LANGUAGE plpgsql
+ AS $$ BEGIN RETURN NULL; END;$$;',
+ regexp => qr/^
+ \QCREATE FUNCTION trigger_func() RETURNS trigger\E
+ \n\s+\QLANGUAGE plpgsql\E
+ \n\s+AS\ \$\$
+ \Q BEGIN RETURN NULL; END;\E
+ \$\$;$/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE FUNCTION dump_test.event_trigger_func' => {
+ create_order => 32,
+ create_sql => 'CREATE FUNCTION dump_test.event_trigger_func()
+ RETURNS event_trigger LANGUAGE plpgsql
+ AS $$ BEGIN RETURN; END;$$;',
+ regexp => qr/^
+ \QCREATE FUNCTION event_trigger_func() RETURNS event_trigger\E
+ \n\s+\QLANGUAGE plpgsql\E
+ \n\s+AS\ \$\$
+ \Q BEGIN RETURN; END;\E
+ \$\$;$/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE EVENT TRIGGER test_event_trigger' => {
+ create_order => 33,
+ create_sql => 'CREATE EVENT TRIGGER test_event_trigger
+ ON ddl_command_start
+ EXECUTE PROCEDURE dump_test.event_trigger_func();',
+ regexp => qr/^
+ \QCREATE EVENT TRIGGER test_event_trigger \E
+ \QON ddl_command_start\E
+ \n\s+\QEXECUTE PROCEDURE dump_test.event_trigger_func();\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ },
+ unlike => {
+ section_pre_data => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'CREATE TRIGGER test_trigger' => {
+ create_order => 31,
+ create_sql => 'CREATE TRIGGER test_trigger
+ BEFORE INSERT ON dump_test.test_table
+ FOR EACH ROW WHEN (NEW.col1 > 10)
+ EXECUTE PROCEDURE dump_test.trigger_func();',
+ regexp => qr/^
+ \QCREATE TRIGGER test_trigger BEFORE INSERT ON test_table \E
+ \QFOR EACH ROW WHEN ((new.col1 > 10)) \E
+ \QEXECUTE PROCEDURE trigger_func();\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ section_pre_data => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ pg_dumpall_globals => 1,
+ },
+ },
+ 'CREATE TYPE dump_test.planets AS ENUM' => {
+ create_order => 37,
+ create_sql => 'CREATE TYPE dump_test.planets
+ AS ENUM ( \'venus\', \'earth\', \'mars\' );',
+ regexp => qr/^
+ \QCREATE TYPE planets AS ENUM (\E
+ \n\s+'venus',
+ \n\s+'earth',
+ \n\s+'mars'
+ \n\);$/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE TYPE dump_test.planets AS ENUM pg_upgrade' => {
+ regexp => qr/^
+ \QCREATE TYPE planets AS ENUM (\E
+ \n\);.*^
+ \QALTER TYPE dump_test.planets ADD VALUE 'venus';\E
+ \n.*^
+ \QALTER TYPE dump_test.planets ADD VALUE 'earth';\E
+ \n.*^
+ \QALTER TYPE dump_test.planets ADD VALUE 'mars';\E
+ \n$/xms,
+ like => {
+ binary_upgrade => 1,
+ },
+ unlike => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE TYPE dump_test.textrange AS RANGE' => {
+ create_order => 38,
+ create_sql => 'CREATE TYPE dump_test.textrange
+ AS RANGE (subtype=text, collation="C");',
+ regexp => qr/^
+ \QCREATE TYPE textrange AS RANGE (\E
+ \n\s+\Qsubtype = text,\E
+ \n\s+\Qcollation = pg_catalog."C"\E
+ \n\);/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE TYPE dump_test.int42' => {
+ create_order => 39,
+ create_sql => 'CREATE TYPE dump_test.int42;',
+ regexp => qr/^CREATE TYPE int42;/m,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE FUNCTION dump_test.int42_in' => {
+ create_order => 40,
+ create_sql => 'CREATE FUNCTION dump_test.int42_in(cstring)
+ RETURNS dump_test.int42 AS \'int4in\'
+ LANGUAGE internal STRICT IMMUTABLE;',
+ regexp => qr/^
+ \QCREATE FUNCTION int42_in(cstring) RETURNS int42\E
+ \n\s+\QLANGUAGE internal IMMUTABLE STRICT\E
+ \n\s+AS\ \$\$int4in\$\$;
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE FUNCTION dump_test.int42_out' => {
+ create_order => 41,
+ create_sql => 'CREATE FUNCTION dump_test.int42_out(dump_test.int42)
+ RETURNS cstring AS \'int4out\'
+ LANGUAGE internal STRICT IMMUTABLE;',
+ regexp => qr/^
+ \QCREATE FUNCTION int42_out(int42) RETURNS cstring\E
+ \n\s+\QLANGUAGE internal IMMUTABLE STRICT\E
+ \n\s+AS\ \$\$int4out\$\$;
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE TYPE dump_test.int42 populated' => {
+ create_order => 42,
+ create_sql => 'CREATE TYPE dump_test.int42 (
+ internallength = 4,
+ input = dump_test.int42_in,
+ output = dump_test.int42_out,
+ alignment = int4,
+ default = 42,
+ passedbyvalue);',
+ regexp => qr/^
+ \QCREATE TYPE int42 (\E
+ \n\s+\QINTERNALLENGTH = 4,\E
+ \n\s+\QINPUT = int42_in,\E
+ \n\s+\QOUTPUT = int42_out,\E
+ \n\s+\QDEFAULT = '42',\E
+ \n\s+\QALIGNMENT = int4,\E
+ \n\s+\QSTORAGE = plain,\E
+ \n\s+PASSEDBYVALUE\n\);
+ $/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE TYPE dump_test.composite' => {
+ create_order => 43,
+ create_sql => 'CREATE TYPE dump_test.composite AS (
+ f1 int,
+ f2 dump_test.int42
+ );',
+ regexp => qr/^
+ \QCREATE TYPE composite AS (\E
+ \n\s+\Qf1 integer,\E
+ \n\s+\Qf2 int42\E
+ \n\);
+ $/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE FOREIGN DATA WRAPPER dummy' => {
+ create_order => 35,
+ create_sql => 'CREATE FOREIGN DATA WRAPPER dummy;',
+ regexp => qr/CREATE FOREIGN DATA WRAPPER dummy;/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'CREATE SERVER s1 FOREIGN DATA WRAPPER dummy' => {
+ create_order => 36,
+ create_sql => 'CREATE SERVER s1 FOREIGN DATA WRAPPER dummy;',
+ regexp => qr/CREATE SERVER s1 FOREIGN DATA WRAPPER dummy;/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+#######################################
+# Currently broken.
+#######################################
+#
+# 'CREATE TRANSFORM FOR int' => {
+# create_order => 34,
+# create_sql => 'CREATE TRANSFORM FOR int LANGUAGE SQL (FROM SQL WITH FUNCTION varchar_transform(internal), TO SQL WITH FUNCTION int4recv(internal));',
+# regexp => qr/CREATE TRANSFORM FOR int LANGUAGE SQL \(FROM SQL WITH FUNCTION varchar_transform\(internal\), TO SQL WITH FUNCTION int4recv\(internal\)\);/m,
+# like => {
+# binary_upgrade => 1,
+# clean => 1,
+# clean_if_exists => 1,
+# createdb => 1,
+# defaults => 1,
+# exclude_dump_test_schema => 1,
+# exclude_test_table => 1,
+# exclude_test_table_data => 1,
+# no_privs => 1,
+# no_owner => 1,
+# schema_only => 1,
+# section_post_data => 1,
+# },
+# unlike => {
+# section_pre_data => 1,
+# only_dump_test_schema => 1,
+# only_dump_test_table => 1,
+# pg_dumpall_globals => 1,
+# test_schema_plus_blobs => 1,
+# },
+# },
+ 'CREATE LANGUAGE pltestlang' => {
+ create_order => 18,
+ create_sql => 'CREATE LANGUAGE pltestlang
+ HANDLER dump_test.pltestlang_call_handler;',
+ regexp => qr/^
+ \QCREATE PROCEDURAL LANGUAGE pltestlang \E
+ \QHANDLER pltestlang_call_handler;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ only_dump_test_schema => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'CREATE MATERIALIZED VIEW matview' => {
+ create_order => 20,
+ create_sql => 'CREATE MATERIALIZED VIEW dump_test.matview (col1) AS
+ SELECT * FROM dump_test.test_table;',
+ regexp => qr/^
+ \QCREATE MATERIALIZED VIEW matview AS\E
+ \n\s+\QSELECT test_table.col1\E
+ \n\s+\QFROM test_table\E
+ \n\s+\QWITH NO DATA;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE MATERIALIZED VIEW matview_second' => {
+ create_order => 21,
+ create_sql => 'CREATE MATERIALIZED VIEW
+ dump_test.matview_second (col1) AS
+ SELECT * FROM dump_test.matview;',
+ regexp => qr/^
+ \QCREATE MATERIALIZED VIEW matview_second AS\E
+ \n\s+\QSELECT matview.col1\E
+ \n\s+\QFROM matview\E
+ \n\s+\QWITH NO DATA;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE POLICY p1 ON test_table' => {
+ create_order => 22,
+ create_sql => 'CREATE POLICY p1 ON dump_test.test_table
+ USING (true)
+ WITH CHECK (true);',
+ regexp => qr/^
+ \QCREATE POLICY p1 ON test_table FOR ALL TO PUBLIC \E
+ \QUSING (true) WITH CHECK (true);\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ section_pre_data => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ pg_dumpall_globals => 1,
+ },
+ },
+ 'CREATE POLICY p2 ON test_table FOR SELECT' => {
+ create_order => 24,
+ create_sql => 'CREATE POLICY p2 ON dump_test.test_table
+ FOR SELECT TO dump_test USING (true);',
+ regexp => qr/^
+ \QCREATE POLICY p2 ON test_table FOR SELECT TO dump_test \E
+ \QUSING (true);\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ section_pre_data => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ pg_dumpall_globals => 1,
+ },
+ },
+ 'CREATE POLICY p3 ON test_table FOR INSERT' => {
+ create_order => 25,
+ create_sql => 'CREATE POLICY p3 ON dump_test.test_table
+ FOR INSERT TO dump_test WITH CHECK (true);',
+ regexp => qr/^
+ \QCREATE POLICY p3 ON test_table FOR INSERT \E
+ \QTO dump_test WITH CHECK (true);\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ section_pre_data => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ pg_dumpall_globals => 1,
+ },
+ },
+ 'CREATE POLICY p4 ON test_table FOR UPDATE' => {
+ create_order => 26,
+ create_sql => 'CREATE POLICY p4 ON dump_test.test_table FOR UPDATE
+ TO dump_test USING (true) WITH CHECK (true);',
+ regexp => qr/^
+ \QCREATE POLICY p4 ON test_table FOR UPDATE TO dump_test \E
+ \QUSING (true) WITH CHECK (true);\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ section_pre_data => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ pg_dumpall_globals => 1,
+ },
+ },
+ 'CREATE POLICY p5 ON test_table FOR DELETE' => {
+ create_order => 27,
+ create_sql => 'CREATE POLICY p5 ON dump_test.test_table
+ FOR DELETE TO dump_test USING (true);',
+ regexp => qr/^
+ \QCREATE POLICY p5 ON test_table FOR DELETE \E
+ \QTO dump_test USING (true);\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ section_pre_data => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ pg_dumpall_globals => 1,
+ },
+ },
+ 'CREATE SCHEMA dump_test' => {
+ create_order => 2,
+ create_sql => 'CREATE SCHEMA dump_test;',
+ regexp => qr/^CREATE SCHEMA dump_test;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE SCHEMA dump_test_second_schema' => {
+ create_order => 9,
+ create_sql => 'CREATE SCHEMA dump_test_second_schema;',
+ regexp => qr/^CREATE SCHEMA dump_test_second_schema;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'CREATE TABLE test_table' => {
+ create_order => 3,
+ create_sql => 'CREATE TABLE dump_test.test_table (
+ col1 serial primary key,
+ CHECK (col1 <= 1000)
+ );',
+ regexp => qr/^
+ \QCREATE TABLE test_table (\E
+ \n\s+\Qcol1 integer NOT NULL,\E
+ \n\s+\QCONSTRAINT test_table_col1_check CHECK \E
+ \Q((col1 <= 1000))\E
+ \n\);$/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE TABLE fk_reference_test_table' => {
+ create_order => 21,
+ create_sql => 'CREATE TABLE dump_test.fk_reference_test_table (
+ col1 int primary key references dump_test.test_table
+ );',
+ regexp => qr/^
+ \QCREATE TABLE fk_reference_test_table (\E
+ \n\s+\Qcol1 integer NOT NULL\E
+ \n\);
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE TABLE test_second_table' => {
+ create_order => 6,
+ create_sql => 'CREATE TABLE dump_test.test_second_table (
+ col1 int,
+ col2 text
+ );',
+ regexp => qr/^
+ \QCREATE TABLE test_second_table (\E
+ \n\s+\Qcol1 integer,\E
+ \n\s+\Qcol2 text\E
+ \n\);
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE TABLE test_third_table' => {
+ create_order => 11,
+ create_sql => 'CREATE TABLE dump_test_second_schema.test_third_table (
+ col1 serial
+ );',
+ regexp => qr/^
+ \QCREATE TABLE test_third_table (\E
+ \n\s+\Qcol1 integer NOT NULL\E
+ \n\);
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'CREATE SEQUENCE test_table_col1_seq' => {
+ regexp => qr/^
+ \QCREATE SEQUENCE test_table_col1_seq\E
+ \n\s+\QSTART WITH 1\E
+ \n\s+\QINCREMENT BY 1\E
+ \n\s+\QNO MINVALUE\E
+ \n\s+\QNO MAXVALUE\E
+ \n\s+\QCACHE 1;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE SEQUENCE test_third_table_col1_seq' => {
+ regexp => qr/^
+ \QCREATE SEQUENCE test_third_table_col1_seq\E
+ \n\s+\QSTART WITH 1\E
+ \n\s+\QINCREMENT BY 1\E
+ \n\s+\QNO MINVALUE\E
+ \n\s+\QNO MAXVALUE\E
+ \n\s+\QCACHE 1;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'CREATE UNIQUE INDEX test_third_table_idx ON test_third_table' => {
+ create_order => 13,
+ create_sql => 'CREATE UNIQUE INDEX test_third_table_idx
+ ON dump_test_second_schema.test_third_table (col1);',
+ regexp => qr/^
+ \QCREATE UNIQUE INDEX test_third_table_idx \E
+ \QON test_third_table USING btree (col1);\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_post_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'CREATE ... commands' => { # catch-all for CREATE
+ regexp => qr/^CREATE /m,
+ like => { }, # use more-specific options above
+ unlike => {
+ column_inserts => 1,
+ data_only => 1,
+ section_data => 1,
+ },
+ },
+ 'DROP EXTENSION plpgsql' => {
+ regexp => qr/^DROP EXTENSION plpgsql;$/m,
+ like => {
+ clean => 1,
+ },
+ unlike => {
+ clean_if_exists => 1,
+ },
+ },
+ 'DROP FUNCTION dump_test.pltestlang_call_handler()' => {
+ regexp => qr/^DROP FUNCTION dump_test\.pltestlang_call_handler\(\);$/m,
+ like => {
+ clean => 1,
+ },
+ unlike => {
+ clean_if_exists => 1,
+ },
+ },
+ 'DROP LANGUAGE pltestlang' => {
+ regexp => qr/^DROP PROCEDURAL LANGUAGE pltestlang;$/m,
+ like => {
+ clean => 1,
+ },
+ unlike => {
+ clean_if_exists => 1,
+ },
+ },
+ 'DROP SCHEMA dump_test' => {
+ regexp => qr/^DROP SCHEMA dump_test;$/m,
+ like => {
+ clean => 1,
+ },
+ unlike => {
+ clean_if_exists => 1,
+ },
+ },
+ 'DROP SCHEMA dump_test_second_schema' => {
+ regexp => qr/^DROP SCHEMA dump_test_second_schema;$/m,
+ like => {
+ clean => 1,
+ },
+ unlike => {
+ clean_if_exists => 1,
+ },
+ },
+ 'DROP TABLE test_table' => {
+ regexp => qr/^DROP TABLE dump_test\.test_table;$/m,
+ like => {
+ clean => 1,
+ },
+ unlike => {
+ clean_if_exists => 1,
+ },
+ },
+ 'DROP TABLE fk_reference_test_table' => {
+ regexp => qr/^DROP TABLE dump_test\.fk_reference_test_table;$/m,
+ like => {
+ clean => 1,
+ },
+ unlike => {
+ clean_if_exists => 1,
+ },
+ },
+ 'DROP TABLE test_second_table' => {
+ regexp => qr/^DROP TABLE dump_test\.test_second_table;$/m,
+ like => {
+ clean => 1,
+ },
+ unlike => {
+ clean_if_exists => 1,
+ },
+ },
+ 'DROP TABLE test_third_table' => {
+ regexp => qr/^DROP TABLE dump_test_second_schema\.test_third_table;$/m,
+ like => {
+ clean => 1,
+ },
+ unlike => {
+ clean_if_exists => 1,
+ },
+ },
+ 'DROP EXTENSION IF EXISTS plpgsql' => {
+ regexp => qr/^DROP EXTENSION IF EXISTS plpgsql;$/m,
+ like => {
+ clean_if_exists => 1,
+ },
+ unlike => {
+ clean => 1,
+ },
+ },
+ 'DROP FUNCTION IF EXISTS dump_test.pltestlang_call_handler()' => {
+ regexp => qr/^
+ \QDROP FUNCTION IF EXISTS dump_test.pltestlang_call_handler();\E
+ $/xm,
+ like => {
+ clean_if_exists => 1,
+ },
+ unlike => {
+ clean => 1,
+ },
+ },
+ 'DROP LANGUAGE IF EXISTS pltestlang' => {
+ regexp => qr/^DROP PROCEDURAL LANGUAGE IF EXISTS pltestlang;$/m,
+ like => {
+ clean_if_exists => 1,
+ },
+ unlike => {
+ clean => 1,
+ },
+ },
+ 'DROP SCHEMA IF EXISTS dump_test' => {
+ regexp => qr/^DROP SCHEMA IF EXISTS dump_test;$/m,
+ like => {
+ clean_if_exists => 1,
+ },
+ unlike => {
+ clean => 1,
+ },
+ },
+ 'DROP SCHEMA IF EXISTS dump_test_second_schema' => {
+ regexp => qr/^DROP SCHEMA IF EXISTS dump_test_second_schema;$/m,
+ like => {
+ clean_if_exists => 1,
+ },
+ unlike => {
+ clean => 1,
+ },
+ },
+ 'DROP TABLE IF EXISTS test_table' => {
+ regexp => qr/^DROP TABLE IF EXISTS dump_test\.test_table;$/m,
+ like => {
+ clean_if_exists => 1,
+ },
+ unlike => {
+ clean => 1,
+ },
+ },
+ 'DROP TABLE IF EXISTS test_second_table' => {
+ regexp => qr/^DROP TABLE IF EXISTS dump_test\.test_second_table;$/m,
+ like => {
+ clean_if_exists => 1,
+ },
+ unlike => {
+ clean => 1,
+ },
+ },
+ 'DROP TABLE IF EXISTS test_third_table' => {
+ regexp => qr/^
+ \QDROP TABLE IF EXISTS dump_test_second_schema.test_third_table;\E
+ $/xm,
+ like => {
+ clean_if_exists => 1,
+ },
+ unlike => {
+ clean => 1,
+ },
+ },
+ 'DROP ... commands' => { # catch-all for DROP
+ regexp => qr/^DROP /m,
+ like => { }, # use more-specific options above
+ unlike => {
+ binary_upgrade => 1,
+ column_inserts => 1,
+ createdb => 1,
+ data_only => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ schema_only => 1,
+ },
+ },
+ 'GRANT USAGE ON SCHEMA dump_test_second_schema' => {
+ create_order => 10,
+ create_sql => 'GRANT USAGE ON SCHEMA dump_test_second_schema
+ TO dump_test;',
+ regexp => qr/^
+ \QGRANT USAGE ON SCHEMA dump_test_second_schema TO dump_test;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'GRANT SELECT ON TABLE test_table' => {
+ create_order => 5,
+ create_sql => 'GRANT SELECT ON TABLE dump_test.test_table
+ TO dump_test;',
+ regexp => qr/^GRANT SELECT ON TABLE test_table TO dump_test;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ pg_dumpall_globals => 1,
+ },
+ },
+ 'GRANT SELECT ON TABLE test_third_table' => {
+ create_order => 19,
+ create_sql => 'GRANT SELECT ON
+ TABLE dump_test_second_schema.test_third_table
+ TO dump_test;',
+ regexp => qr/^GRANT SELECT ON TABLE test_third_table TO dump_test;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'GRANT ALL ON SEQUENCE test_third_table_col1_seq' => {
+ create_order => 28,
+ create_sql => 'GRANT ALL ON SEQUENCE
+ dump_test_second_schema.test_third_table_col1_seq
+ TO dump_test;',
+ regexp => qr/^
+ \QGRANT ALL ON SEQUENCE test_third_table_col1_seq TO dump_test;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'GRANT INSERT(col1) ON TABLE test_second_table' => {
+ create_order => 8,
+ create_sql => 'GRANT INSERT (col1) ON TABLE dump_test.test_second_table
+ TO dump_test;',
+ regexp => qr/^
+ \QGRANT INSERT(col1) ON TABLE test_second_table TO dump_test;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ test_schema_plus_blobs => 1,
+ },
+ unlike => {
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ },
+ },
+ 'GRANT EXECUTE ON FUNCTION pg_sleep() TO dump_test' => {
+ create_order => 16,
+ create_sql => 'GRANT EXECUTE ON FUNCTION pg_sleep(float8)
+ TO dump_test;',
+ regexp => qr/^
+ \QGRANT ALL ON FUNCTION pg_sleep(double precision) TO dump_test;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'GRANT SELECT (proname ...) ON TABLE pg_proc TO public' => {
+ create_order => 46,
+ create_sql => 'GRANT SELECT (
+ tableoid,
+ oid,
+ proname,
+ pronamespace,
+ proowner,
+ prolang,
+ procost,
+ prorows,
+ provariadic,
+ protransform,
+ proisagg,
+ proiswindow,
+ prosecdef,
+ proleakproof,
+ proisstrict,
+ proretset,
+ provolatile,
+ proparallel,
+ pronargs,
+ pronargdefaults,
+ prorettype,
+ proargtypes,
+ proallargtypes,
+ proargmodes,
+ proargnames,
+ proargdefaults,
+ protrftypes,
+ prosrc,
+ probin,
+ proconfig,
+ proacl
+ ) ON TABLE pg_proc TO public;',
+ regexp => qr/
+ \QGRANT SELECT(tableoid) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(oid) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proname) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(pronamespace) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proowner) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(prolang) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(procost) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(prorows) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(provariadic) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(protransform) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proisagg) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proiswindow) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(prosecdef) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proleakproof) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proisstrict) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proretset) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(provolatile) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proparallel) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(pronargs) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(pronargdefaults) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(prorettype) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proargtypes) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proallargtypes) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proargmodes) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proargnames) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proargdefaults) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(protrftypes) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(prosrc) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(probin) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proconfig) ON TABLE pg_proc TO PUBLIC;\E\n.*
+ \QGRANT SELECT(proacl) ON TABLE pg_proc TO PUBLIC;\E$/xms,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'GRANT commands' => { # catch-all for GRANT commands
+ regexp => qr/^GRANT /m,
+ like => { }, # use more-specific options above
+ unlike => {
+ column_inserts => 1,
+ data_only => 1,
+ no_privs => 1,
+ section_data => 1,
+ },
+ },
+ 'REFRESH MATERIALIZED VIEW matview' => {
+ regexp => qr/^REFRESH MATERIALIZED VIEW matview;$/m,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ test_schema_plus_blobs => 1,
+ section_post_data => 1,
+ },
+ unlike => {
+ binary_upgrade => 1,
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ },
+ 'REFRESH MATERIALIZED VIEW matview_second' => {
+ regexp => qr/^
+ \QREFRESH MATERIALIZED VIEW matview;\E
+ \n.*
+ \QREFRESH MATERIALIZED VIEW matview_second;\E
+ $/xms,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_privs => 1,
+ no_owner => 1,
+ only_dump_test_schema => 1,
+ test_schema_plus_blobs => 1,
+ section_post_data => 1,
+ },
+ unlike => {
+ binary_upgrade => 1,
+ exclude_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ pg_dumpall_globals => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ },
+ 'REVOKE EXECUTE ON FUNCTION pg_sleep() FROM public' => {
+ create_order => 15,
+ create_sql => 'REVOKE EXECUTE ON FUNCTION pg_sleep(float8)
+ FROM public;',
+ regexp => qr/^
+ \QREVOKE ALL ON FUNCTION pg_sleep(double precision) FROM PUBLIC;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'REVOKE SELECT ON TABLE pg_proc FROM public' => {
+ create_order => 45,
+ create_sql => 'REVOKE SELECT ON TABLE pg_proc FROM public;',
+ regexp => qr/^REVOKE SELECT ON TABLE pg_proc FROM PUBLIC;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'REVOKE CREATE ON SCHEMA public FROM public' => {
+ create_order => 16,
+ create_sql => 'REVOKE CREATE ON SCHEMA public FROM public;',
+ regexp => qr/^
+ \QREVOKE ALL ON SCHEMA public FROM PUBLIC;\E
+ \n\QGRANT USAGE ON SCHEMA public TO PUBLIC;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'REVOKE USAGE ON LANGUAGE plpgsql FROM public' => {
+ create_order => 16,
+ create_sql => 'REVOKE USAGE ON LANGUAGE plpgsql FROM public;',
+ regexp => qr/^REVOKE ALL ON LANGUAGE plpgsql FROM PUBLIC;$/m,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ exclude_dump_test_schema => 1,
+ exclude_test_table => 1,
+ exclude_test_table_data => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ only_dump_test_schema => 1,
+ only_dump_test_table => 1,
+ test_schema_plus_blobs => 1,
+ },
+ },
+ 'REVOKE commands' => { # catch-all for REVOKE commands
+ regexp => qr/^REVOKE /m,
+ like => { }, # use more-specific options above
+ unlike => {
+ column_inserts => 1,
+ data_only => 1,
+ no_privs => 1,
+ pg_dumpall_globals => 1,
+ },
+ },
+);
+
+#########################################
+# Create a PG instance to test actually dumping from
+
+my $node = get_new_node('main');
+$node->init;
+$node->start;
+
+my $port = $node->port;
+
+# Start with 2 because of command_exit_is() tests below
+my $num_tests = 2;
+
+foreach my $run (sort keys %pgdump_runs) {
+ my $test_key = $run;
+
+ # Each run of pg_dump is a test itself
+ $num_tests++;
+
+ # If there is a restore cmd, that's another test
+ if ($pgdump_runs{$run}->{restore_cmd}) {
+ $num_tests++;
+ }
+
+ if ($pgdump_runs{$run}->{test_key}) {
+ $test_key = $pgdump_runs{$run}->{test_key};
+ }
+
+ # Then count all the tests run against each run
+ foreach my $test (sort keys %tests) {
+ if ($tests{$test}->{like}->{$test_key}) {
+ $num_tests++;
+ }
+
+ if ($tests{$test}->{unlike}->{$test_key}) {
+ $num_tests++;
+ }
+ }
+}
+plan tests => $num_tests;
+
+#########################################
+# Set up schemas, tables, etc, to be dumped.
+
+# Build up the create statements
+my $create_sql = '';
+
+foreach my $test (
+ sort {
+ if ($tests{$a}->{create_order} and $tests{$b}->{create_order}) {
+ $tests{$a}->{create_order} <=> $tests{$b}->{create_order};
+ } elsif ($tests{$a}->{create_order}) {
+ -1;
+ } elsif ($tests{$b}->{create_order}) {
+ 1;
+ } else {
+ 0;
+ }
+ } keys %tests) {
+ if ($tests{$test}->{create_sql}) {
+ $create_sql .= $tests{$test}->{create_sql};
+ }
+}
+
+# Send the combined set of commands to psql
+$node->safe_psql('postgres', $create_sql);
+
+#########################################
+# Test connecting to a non-existent database
+
+command_exit_is([ 'pg_dump', '-p', "$port", 'qqq' ],
+ 1, 'pg_dump: [archiver (db)] connection to database "qqq" failed: FATAL: database "qqq" does not exist');
+
+command_exit_is([ 'pg_dump', '-p', "$port", '--role=dump_test' ],
+ 1, 'pg_dump: [archiver (db)] query failed: ERROR: permission denied for');
+
+#########################################
+# Run all runs
+
+foreach my $run (sort keys %pgdump_runs) {
+
+ my $test_key = $run;
+
+ $node->command_ok(\@{ $pgdump_runs{$run}->{dump_cmd} }, "$run: pg_dump runs");
+
+ if ($pgdump_runs{$run}->{restore_cmd}) {
+ $node->command_ok(\@{ $pgdump_runs{$run}->{restore_cmd} }, "$run: pg_restore runs");
+ }
+
+ if ($pgdump_runs{$run}->{test_key}) {
+ $test_key = $pgdump_runs{$run}->{test_key};
+ }
+
+ my $output_file = slurp_file("$tempdir/${run}.sql");
+
+ #########################################
+ # Run all tests where this run is included
+ # as either a 'like' or 'unlike' test.
+
+ foreach my $test (sort keys %tests) {
+ if ($tests{$test}->{like}->{$test_key}) {
+ like($output_file, $tests{$test}->{regexp}, "$run: dumps $test");
+ }
+
+ if ($tests{$test}->{unlike}->{$test_key}) {
+ unlike($output_file, $tests{$test}->{regexp}, "$run: does not dump $test");
+ }
+ }
+}
+
+#########################################
+# Stop the database instance, which will be removed at the end of the tests.
+
+$node->stop('fast');
diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile
index 9b935521f47..892662755a8 100644
--- a/src/test/modules/Makefile
+++ b/src/test/modules/Makefile
@@ -12,6 +12,7 @@ SUBDIRS = \
test_ddl_deparse \
test_extensions \
test_parser \
+ test_pg_dump \
test_rls_hooks \
test_shm_mq \
worker_spi
diff --git a/src/test/modules/test_pg_dump/.gitignore b/src/test/modules/test_pg_dump/.gitignore
new file mode 100644
index 00000000000..5dcb3ff9723
--- /dev/null
+++ b/src/test/modules/test_pg_dump/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/src/test/modules/test_pg_dump/Makefile b/src/test/modules/test_pg_dump/Makefile
new file mode 100644
index 00000000000..0eb3b5f988e
--- /dev/null
+++ b/src/test/modules/test_pg_dump/Makefile
@@ -0,0 +1,25 @@
+# src/test/modules/test_rls_hooks/Makefile
+
+MODULE_big = test_pg_dump
+PGFILEDESC = "test_pg_dump - Test pg_dump with an extension"
+
+EXTENSION = test_pg_dump
+DATA = test_pg_dump--1.0.sql
+
+REGRESS = test_pg_dump
+
+check: prove-check
+
+prove-check:
+ $(prove_check)
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/test_pg_dump
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/src/test/modules/test_pg_dump/README b/src/test/modules/test_pg_dump/README
new file mode 100644
index 00000000000..e6c78b822c3
--- /dev/null
+++ b/src/test/modules/test_pg_dump/README
@@ -0,0 +1,2 @@
+test_pg_dump is an extension explicitly to test pg_dump when
+extensions are present in the system.
diff --git a/src/test/modules/test_pg_dump/expected/test_pg_dump.out b/src/test/modules/test_pg_dump/expected/test_pg_dump.out
new file mode 100644
index 00000000000..360caa2cb30
--- /dev/null
+++ b/src/test/modules/test_pg_dump/expected/test_pg_dump.out
@@ -0,0 +1,6 @@
+SELECT 1;
+ ?column?
+----------
+ 1
+(1 row)
+
diff --git a/src/test/modules/test_pg_dump/sql/test_pg_dump.sql b/src/test/modules/test_pg_dump/sql/test_pg_dump.sql
new file mode 100644
index 00000000000..e0ac49d1ecf
--- /dev/null
+++ b/src/test/modules/test_pg_dump/sql/test_pg_dump.sql
@@ -0,0 +1 @@
+SELECT 1;
diff --git a/src/test/modules/test_pg_dump/t/001_base.pl b/src/test/modules/test_pg_dump/t/001_base.pl
new file mode 100644
index 00000000000..9a65da1d6ae
--- /dev/null
+++ b/src/test/modules/test_pg_dump/t/001_base.pl
@@ -0,0 +1,535 @@
+use strict;
+use warnings;
+
+use Config;
+use PostgresNode;
+use TestLib;
+use Test::More;
+
+my $tempdir = TestLib::tempdir;
+my $tempdir_short = TestLib::tempdir_short;
+
+###############################################################
+# This structure is based off of the src/bin/pg_dump/t test
+# suite.
+###############################################################
+# Definition of the pg_dump runs to make.
+#
+# Each of these runs are named and those names are used below
+# to define how each test should (or shouldn't) treat a result
+# from a given run.
+#
+# test_key indicates that a given run should simply use the same
+# set of like/unlike tests as another run, and which run that is.
+#
+# dump_cmd is the pg_dump command to run, which is an array of
+# the full command and arguments to run. Note that this is run
+# using $node->command_ok(), so the port does not need to be
+# specified and is pulled from $PGPORT, which is set by the
+# PostgresNode system.
+#
+# restore_cmd is the pg_restore command to run, if any. Note
+# that this should generally be used when the pg_dump goes to
+# a non-text file and that the restore can then be used to
+# generate a text file to run through the tests from the
+# non-text file generated by pg_dump.
+#
+# TODO: Have pg_restore actually restore to an independent
+# database and then pg_dump *that* database (or something along
+# those lines) to validate that part of the process.
+
+my %pgdump_runs = (
+ binary_upgrade => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/binary_upgrade.sql",
+ '--schema-only',
+ '--binary-upgrade',
+ '-d', 'postgres', # alternative way to specify database
+ ],
+ },
+ clean => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/clean.sql",
+ '-c',
+ '-d', 'postgres', # alternative way to specify database
+ ],
+ },
+ clean_if_exists => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/clean_if_exists.sql",
+ '-c',
+ '--if-exists',
+ '-E', 'UTF8', # no-op, just tests that option is accepted
+ 'postgres',
+ ],
+ },
+ column_inserts => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/column_inserts.sql",
+ '-a',
+ '--column-inserts',
+ 'postgres',
+ ],
+ },
+ createdb => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/createdb.sql",
+ '-C',
+ '-R', # no-op, just for testing
+ 'postgres',
+ ],
+ },
+ data_only => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/data_only.sql",
+ '-a',
+ '-v', # no-op, just make sure it works
+ 'postgres',
+ ],
+ },
+ defaults => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/defaults.sql",
+ 'postgres',
+ ],
+ },
+ defaults_custom_format => {
+ test_key => 'defaults',
+ dump_cmd => [
+ 'pg_dump',
+ '-Fc',
+ '-Z6',
+ '-f', "$tempdir/defaults_custom_format.dump",
+ 'postgres',
+ ],
+ restore_cmd => [
+ 'pg_restore',
+ '-f', "$tempdir/defaults_custom_format.sql",
+ "$tempdir/defaults_custom_format.dump",
+ ],
+ },
+ defaults_dir_format => {
+ test_key => 'defaults',
+ dump_cmd => [
+ 'pg_dump',
+ '-Fd',
+ '-f', "$tempdir/defaults_dir_format",
+ 'postgres',
+ ],
+ restore_cmd => [
+ 'pg_restore',
+ '-f', "$tempdir/defaults_dir_format.sql",
+ "$tempdir/defaults_dir_format",
+ ],
+ },
+ defaults_parallel => {
+ test_key => 'defaults',
+ dump_cmd => [
+ 'pg_dump',
+ '-Fd',
+ '-j2',
+ '-f', "$tempdir/defaults_parallel",
+ 'postgres',
+ ],
+ restore_cmd => [
+ 'pg_restore',
+ '-f', "$tempdir/defaults_parallel.sql",
+ "$tempdir/defaults_parallel",
+ ],
+ },
+ defaults_tar_format => {
+ test_key => 'defaults',
+ dump_cmd => [
+ 'pg_dump',
+ '-Ft',
+ '-f', "$tempdir/defaults_tar_format.tar",
+ 'postgres',
+ ],
+ restore_cmd => [
+ 'pg_restore',
+ '-f', "$tempdir/defaults_tar_format.sql",
+ "$tempdir/defaults_tar_format.tar",
+ ],
+ },
+ pg_dumpall_globals => {
+ dump_cmd => [
+ 'pg_dumpall',
+ '-f', "$tempdir/pg_dumpall_globals.sql",
+ '-g',
+ ],
+ },
+ no_privs => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/no_privs.sql",
+ '-x',
+ 'postgres',
+ ],
+ },
+ no_owner => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/no_owner.sql",
+ '-O',
+ 'postgres',
+ ],
+ },
+ schema_only => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/schema_only.sql",
+ '-s',
+ 'postgres',
+ ],
+ },
+ section_pre_data => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/section_pre_data.sql",
+ '--section=pre-data',
+ 'postgres',
+ ],
+ },
+ section_data => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/section_data.sql",
+ '--section=data',
+ 'postgres',
+ ],
+ },
+ section_post_data => {
+ dump_cmd => [
+ 'pg_dump',
+ '-f', "$tempdir/section_post_data.sql",
+ '--section=post-data',
+ 'postgres',
+ ],
+ },
+);
+
+###############################################################
+# Definition of the tests to run.
+#
+# Each test is defined using the log message that will be used.
+#
+# A regexp should be defined for each test which provides the
+# basis for the test. That regexp will be run against the output
+# file of each of the runs which the test is to be run against
+# and the success of the result will depend on if the regexp
+# result matches the expected 'like' or 'unlike' case.
+#
+# For each test, there are two sets of runs defined, one for
+# the 'like' tests and one for the 'unlike' tests. 'like'
+# essentially means "the regexp for this test must match the
+# output file". 'unlike' is the opposite.
+#
+# There are a few 'catch-all' tests which can be used to have
+# a single, simple, test to over a range of other tests. For
+# example, there is a '^CREATE ' test, which is used for the
+# 'data-only' test as there should never be any kind of CREATE
+# statement in a 'data-only' run. Without the catch-all, we
+# would have to list the 'data-only' run in each and every
+# 'CREATE xxxx' test, which would be a lot of additional tests.
+#
+# Note that it makes no sense for the same run to ever be listed
+# in both 'like' and 'unlike' categories.
+#
+# There can then be a 'create_sql' and 'create_order' for a
+# given test. The 'create_sql' commands are collected up in
+# 'create_order' and then run against the database prior to any
+# of the pg_dump runs happening. This is what "seeds" the
+# system with objects to be dumped out.
+#
+# Building of this hash takes a bit of time as all of the regexps
+# included in it are compiled. This greatly improves performance
+# as the regexps are used for each run the test applies to.
+
+my %tests = (
+ 'CREATE EXTENSION test_pg_dump' => {
+ create_order => 2,
+ create_sql => 'CREATE EXTENSION test_pg_dump;',
+ regexp => qr/^
+ \QCREATE EXTENSION IF NOT EXISTS test_pg_dump WITH SCHEMA public;\E
+ $/xm,
+ like => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ binary_upgrade => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE ROLE dump_test' => {
+ create_order => 1,
+ create_sql => 'CREATE ROLE dump_test;',
+ regexp => qr/^CREATE ROLE dump_test;$/m,
+ like => {
+ pg_dumpall_globals => 1,
+ },
+ unlike => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ section_post_data => 1,
+ },
+ },
+ 'CREATE TABLE regress_pg_dump_table' => {
+ regexp => qr/^
+ \QCREATE TABLE regress_pg_dump_table (\E
+ \n\s+\Qcol1 integer,\E
+ \n\s+\Qcol2 integer\E
+ \n\);$/xm,
+ like => {
+ binary_upgrade => 1,
+ },
+ unlike => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ no_privs => 1,
+ no_owner => 1,
+ pg_dumpall_globals => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ section_post_data => 1,
+ },
+ },
+ 'COMMENT ON EXTENSION test_pg_dump' => {
+ regexp => qr/^
+ \QCOMMENT ON EXTENSION test_pg_dump \E
+ \QIS 'Test pg_dump with an extension';\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ no_privs => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'GRANT SELECT ON TABLE regress_pg_dump_table' => {
+ regexp => qr/^
+ \QSELECT binary_upgrade_set_record_init_privs(true);\E\n
+ \QGRANT SELECT ON TABLE regress_pg_dump_table TO dump_test;\E\n
+ \QSELECT binary_upgrade_set_record_init_privs(false);\E
+ $/xms,
+ like => {
+ binary_upgrade => 1,
+ },
+ unlike => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ no_privs => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'GRANT SELECT(col1) ON regress_pg_dump_table' => {
+ regexp => qr/^
+ \QSELECT binary_upgrade_set_record_init_privs(true);\E\n
+ \QGRANT SELECT(col1) ON TABLE regress_pg_dump_table TO PUBLIC;\E\n
+ \QSELECT binary_upgrade_set_record_init_privs(false);\E
+ $/xms,
+ like => {
+ binary_upgrade => 1,
+ },
+ unlike => {
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ no_privs => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'GRANT SELECT(col2) ON regress_pg_dump_table TO dump_test' => {
+ create_order => 4,
+ create_sql => 'GRANT SELECT(col2) ON regress_pg_dump_table
+ TO dump_test;',
+ regexp => qr/^
+ \QGRANT SELECT(col2) ON TABLE regress_pg_dump_table TO dump_test;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ no_privs => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+ 'REVOKE SELECT(col1) ON regress_pg_dump_table' => {
+ create_order => 3,
+ create_sql => 'REVOKE SELECT(col1) ON regress_pg_dump_table
+ FROM PUBLIC;',
+ regexp => qr/^
+ \QREVOKE SELECT(col1) ON TABLE regress_pg_dump_table FROM PUBLIC;\E
+ $/xm,
+ like => {
+ binary_upgrade => 1,
+ clean => 1,
+ clean_if_exists => 1,
+ createdb => 1,
+ defaults => 1,
+ no_owner => 1,
+ schema_only => 1,
+ section_pre_data => 1,
+ },
+ unlike => {
+ no_privs => 1,
+ pg_dumpall_globals => 1,
+ section_post_data => 1,
+ },
+ },
+);
+
+#########################################
+# Create a PG instance to test actually dumping from
+
+my $node = get_new_node('main');
+$node->init;
+$node->start;
+
+my $port = $node->port;
+
+my $num_tests = 0;
+
+foreach my $run (sort keys %pgdump_runs) {
+ my $test_key = $run;
+
+ # Each run of pg_dump is a test itself
+ $num_tests++;
+
+ # If there is a restore cmd, that's another test
+ if ($pgdump_runs{$run}->{restore_cmd}) {
+ $num_tests++;
+ }
+
+ if ($pgdump_runs{$run}->{test_key}) {
+ $test_key = $pgdump_runs{$run}->{test_key};
+ }
+
+ # Then count all the tests run against each run
+ foreach my $test (sort keys %tests) {
+ if ($tests{$test}->{like}->{$test_key}) {
+ $num_tests++;
+ }
+
+ if ($tests{$test}->{unlike}->{$test_key}) {
+ $num_tests++;
+ }
+ }
+}
+plan tests => $num_tests;
+
+#########################################
+# Set up schemas, tables, etc, to be dumped.
+
+# Build up the create statements
+my $create_sql = '';
+
+foreach my $test (
+ sort {
+ if ($tests{$a}->{create_order} and $tests{$b}->{create_order}) {
+ $tests{$a}->{create_order} <=> $tests{$b}->{create_order};
+ } elsif ($tests{$a}->{create_order}) {
+ -1;
+ } elsif ($tests{$b}->{create_order}) {
+ 1;
+ } else {
+ 0;
+ }
+ } keys %tests) {
+ if ($tests{$test}->{create_sql}) {
+ $create_sql .= $tests{$test}->{create_sql};
+ }
+}
+
+# Send the combined set of commands to psql
+$node->safe_psql('postgres', $create_sql);
+
+#########################################
+# Run all runs
+
+foreach my $run (sort keys %pgdump_runs) {
+
+ my $test_key = $run;
+
+ $node->command_ok(\@{ $pgdump_runs{$run}->{dump_cmd} }, "$run: pg_dump runs");
+
+ if ($pgdump_runs{$run}->{restore_cmd}) {
+ $node->command_ok(\@{ $pgdump_runs{$run}->{restore_cmd} }, "$run: pg_restore runs");
+ }
+
+ if ($pgdump_runs{$run}->{test_key}) {
+ $test_key = $pgdump_runs{$run}->{test_key};
+ }
+
+ my $output_file = slurp_file("$tempdir/${run}.sql");
+
+ #########################################
+ # Run all tests where this run is included
+ # as either a 'like' or 'unlike' test.
+
+ foreach my $test (sort keys %tests) {
+ if ($tests{$test}->{like}->{$test_key}) {
+ like($output_file, $tests{$test}->{regexp}, "$run: dumps $test");
+ }
+
+ if ($tests{$test}->{unlike}->{$test_key}) {
+ unlike($output_file, $tests{$test}->{regexp}, "$run: does not dump $test");
+ }
+ }
+}
+
+#########################################
+# Stop the database instance, which will be removed at the end of the tests.
+
+$node->stop('fast');
diff --git a/src/test/modules/test_pg_dump/test_pg_dump--1.0.sql b/src/test/modules/test_pg_dump/test_pg_dump--1.0.sql
new file mode 100644
index 00000000000..d1ec58d023f
--- /dev/null
+++ b/src/test/modules/test_pg_dump/test_pg_dump--1.0.sql
@@ -0,0 +1,15 @@
+/* src/test/modules/test_pg_dump/test_pg_dump--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION test_pg_dump" to load this file. \quit
+
+CREATE TABLE regress_pg_dump_table (
+ col1 int,
+ col2 int
+);
+
+GRANT SELECT ON regress_pg_dump_table TO dump_test;
+GRANT SELECT(col1) ON regress_pg_dump_table TO public;
+
+GRANT SELECT(col2) ON regress_pg_dump_table TO dump_test;
+REVOKE SELECT(col2) ON regress_pg_dump_table FROM dump_test;
diff --git a/src/test/modules/test_pg_dump/test_pg_dump.control b/src/test/modules/test_pg_dump/test_pg_dump.control
new file mode 100644
index 00000000000..fe3450db76c
--- /dev/null
+++ b/src/test/modules/test_pg_dump/test_pg_dump.control
@@ -0,0 +1,3 @@
+comment = 'Test pg_dump with an extension'
+default_version = '1.0'
+relocatable = true