Skip to content

Commit 4500edc

Browse files
committed
Do not require 'public' to exist for pg_dump -c
Commit 330b84d didn't contemplate the case where the public schema has been dropped and introduced a query which fails when there is no public schema into pg_dump (when used with -c). Adjust the query used by pg_dump to handle the case where the public schema doesn't exist and add tests to check that such a case no longer fails. Back-patch the specific fix to 9.6, as the prior commit was. Adding tests for this case involved adding support to the pg_dump TAP tests to work with multiple databases, which, while not a large change, is a bit much to back-patch, so that's only done in master. Addresses bug #14650 Discussion: https://www.postgresql.org/message-id/20170512181801.1795.47483%40wrigleys.postgresql.org
1 parent f0256c7 commit 4500edc

File tree

2 files changed

+113
-4
lines changed

2 files changed

+113
-4
lines changed

src/bin/pg_dump/pg_dump.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -4135,9 +4135,14 @@ getNamespaces(Archive *fout, int *numNamespaces)
41354135
* essentially a no-op because the new public schema won't have an
41364136
* entry in pg_init_privs anyway, as the entry will be removed when
41374137
* the public schema is dropped.
4138+
*
4139+
* Further, we have to handle the case where the public schema does
4140+
* not exist at all.
41384141
*/
41394142
if (dopt->outputClean)
4140-
appendPQExpBuffer(query, " AND pip.objoid <> 'public'::regnamespace");
4143+
appendPQExpBuffer(query, " AND pip.objoid <> "
4144+
"coalesce((select oid from pg_namespace "
4145+
"where nspname = 'public'),0)");
41414146

41424147
appendPQExpBuffer(query, ") ");
41434148

src/bin/pg_dump/t/002_pg_dump.pl

+107-3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,23 @@
9797
'pg_dump', '--no-sync',
9898
'-f', "$tempdir/defaults.sql",
9999
'postgres', ], },
100+
defaults_no_public => {
101+
database => 'regress_pg_dump_test',
102+
dump_cmd => [
103+
'pg_dump',
104+
'--no-sync',
105+
'-f',
106+
"$tempdir/defaults_no_public.sql",
107+
'regress_pg_dump_test', ], },
108+
defaults_no_public_clean => {
109+
database => 'regress_pg_dump_test',
110+
dump_cmd => [
111+
'pg_dump',
112+
'--no-sync',
113+
'-c',
114+
'-f',
115+
"$tempdir/defaults_no_public_clean.sql",
116+
'regress_pg_dump_test', ], },
100117

101118
# Do not use --no-sync to give test coverage for data sync.
102119
defaults_custom_format => {
@@ -4524,6 +4541,35 @@
45244541
pg_dumpall_globals_clean => 1,
45254542
test_schema_plus_blobs => 1, }, },
45264543
4544+
'CREATE SCHEMA public' => {
4545+
all_runs => 1,
4546+
catch_all => 'CREATE ... commands',
4547+
regexp => qr/^CREATE SCHEMA public;/m,
4548+
like => {
4549+
clean => 1,
4550+
clean_if_exists => 1, },
4551+
unlike => {
4552+
binary_upgrade => 1,
4553+
createdb => 1,
4554+
defaults => 1,
4555+
exclude_test_table => 1,
4556+
exclude_test_table_data => 1,
4557+
no_blobs => 1,
4558+
no_privs => 1,
4559+
no_owner => 1,
4560+
only_dump_test_schema => 1,
4561+
pg_dumpall_dbprivs => 1,
4562+
schema_only => 1,
4563+
section_pre_data => 1,
4564+
test_schema_plus_blobs => 1,
4565+
with_oids => 1,
4566+
exclude_dump_test_schema => 1,
4567+
only_dump_test_table => 1,
4568+
pg_dumpall_globals => 1,
4569+
pg_dumpall_globals_clean => 1,
4570+
role => 1,
4571+
section_post_data => 1, }, },
4572+
45274573
'CREATE SCHEMA dump_test' => {
45284574
all_runs => 1,
45294575
catch_all => 'CREATE ... commands',
@@ -5219,6 +5265,34 @@
52195265
data_only => 1,
52205266
section_data => 1, }, },
52215267
5268+
'DROP SCHEMA public (for testing without public schema)' => {
5269+
all_runs => 1,
5270+
database => 'regress_pg_dump_test',
5271+
create_order => 100,
5272+
create_sql => 'DROP SCHEMA public;',
5273+
regexp => qr/^DROP SCHEMA public;/m,
5274+
like => { },
5275+
unlike => { defaults_no_public => 1,
5276+
defaults_no_public_clean => 1, } },
5277+
5278+
'DROP SCHEMA public' => {
5279+
all_runs => 1,
5280+
catch_all => 'DROP ... commands',
5281+
regexp => qr/^DROP SCHEMA public;/m,
5282+
like => { clean => 1 },
5283+
unlike => {
5284+
clean_if_exists => 1,
5285+
pg_dumpall_globals_clean => 1, }, },
5286+
5287+
'DROP SCHEMA IF EXISTS public' => {
5288+
all_runs => 1,
5289+
catch_all => 'DROP ... commands',
5290+
regexp => qr/^DROP SCHEMA IF EXISTS public;/m,
5291+
like => { clean_if_exists => 1 },
5292+
unlike => {
5293+
clean => 1,
5294+
pg_dumpall_globals_clean => 1, }, },
5295+
52225296
'DROP EXTENSION plpgsql' => {
52235297
all_runs => 1,
52245298
catch_all => 'DROP ... commands',
@@ -6433,13 +6507,21 @@
64336507
$collation_support = 1;
64346508
}
64356509
6510+
# Create a second database for certain tests to work against
6511+
$node->psql('postgres','create database regress_pg_dump_test;');
6512+
64366513
# Start with number of command_fails_like()*2 tests below (each
64376514
# command_fails_like is actually 2 tests)
64386515
my $num_tests = 12;
64396516
64406517
foreach my $run (sort keys %pgdump_runs)
64416518
{
64426519
my $test_key = $run;
6520+
my $run_db = 'postgres';
6521+
6522+
if (defined($pgdump_runs{$run}->{database})) {
6523+
$run_db = $pgdump_runs{$run}->{database};
6524+
}
64436525
64446526
# Each run of pg_dump is a test itself
64456527
$num_tests++;
@@ -6458,6 +6540,19 @@
64586540
# Then count all the tests run against each run
64596541
foreach my $test (sort keys %tests)
64606542
{
6543+
# postgres is the default database, if it isn't overridden
6544+
my $test_db = 'postgres';
6545+
6546+
# Specific tests can override the database to use
6547+
if (defined($tests{$test}->{database})) {
6548+
$test_db = $tests{$test}->{database};
6549+
}
6550+
6551+
# The database to test against needs to match the database the run is
6552+
# for, so skip combinations where they don't match up.
6553+
if ($run_db ne $test_db) {
6554+
next;
6555+
}
64616556
64626557
# Skip any collation-related commands if there is no collation support
64636558
if (!$collation_support && defined($tests{$test}->{collation}))
@@ -6507,7 +6602,7 @@
65076602
# Set up schemas, tables, etc, to be dumped.
65086603
65096604
# Build up the create statements
6510-
my $create_sql = '';
6605+
my %create_sql = ();
65116606
65126607
foreach my $test (
65136608
sort {
@@ -6529,6 +6624,12 @@
65296624
}
65306625
} keys %tests)
65316626
{
6627+
my $test_db = 'postgres';
6628+
6629+
if (defined($tests{$test}->{database})) {
6630+
$test_db = $tests{$test}->{database};
6631+
}
6632+
65326633
if ($tests{$test}->{create_sql})
65336634
{
65346635
@@ -6539,12 +6640,15 @@
65396640
}
65406641
65416642
# Add terminating semicolon
6542-
$create_sql .= $tests{$test}->{create_sql} . ";";
6643+
$create_sql{$test_db} .= $tests{$test}->{create_sql} . ";";
65436644
}
65446645
}
65456646
65466647
# Send the combined set of commands to psql
6547-
$node->safe_psql('postgres', $create_sql);
6648+
foreach my $db (sort keys %create_sql)
6649+
{
6650+
$node->safe_psql($db, $create_sql{$db});
6651+
}
65486652
65496653
#########################################
65506654
# Test connecting to a non-existent database

0 commit comments

Comments
 (0)