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