007_schema_only_roles.pl
application/octet-stream
Filename: 007_schema_only_roles.pl
Type: application/octet-stream
Part: 0
# Copyright (c) 2021-2026, PostgreSQL Global Development Group
# Test that pg_dumpall --schema-only produces a restorable dump
# when custom roles own database objects.
#
# This test demonstrates a regression: previously --schema-only would
# include roles and tablespaces (cluster-level schema), but with the
# new conflict detection changes, --schema-only now skips globals,
# making the dump unrestorable when objects have custom owners.
use strict;
use warnings FATAL => 'all';
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More;
my $tempdir = PostgreSQL::Test::Utils::tempdir;
# Create source cluster
my $src = PostgreSQL::Test::Cluster->new('source');
$src->init;
$src->start;
# Create a custom role that will own objects
$src->safe_psql('postgres', 'CREATE ROLE regress_custom_owner LOGIN');
# Create a database owned by the custom role
$src->safe_psql('postgres',
'CREATE DATABASE regress_testdb OWNER regress_custom_owner');
# Create a table in that database owned by the custom role
$src->safe_psql('regress_testdb', q{
SET ROLE regress_custom_owner;
CREATE TABLE regress_test_table (id int PRIMARY KEY, data text);
COMMENT ON TABLE regress_test_table IS 'Table with custom owner';
});
# Also create a schema owned by the custom role in postgres database
$src->safe_psql('postgres', q{
CREATE SCHEMA regress_custom_schema AUTHORIZATION regress_custom_owner;
SET ROLE regress_custom_owner;
CREATE TABLE regress_custom_schema.another_table (x int);
});
# Dump with --schema-only
my $dumpfile = "$tempdir/schema_only_dump.sql";
$src->command_ok(
[
'pg_dumpall',
'--schema-only',
'--no-sync',
'--file' => $dumpfile,
],
'pg_dumpall --schema-only succeeds');
# Create destination cluster for restore test
my $dst = PostgreSQL::Test::Cluster->new('destination');
$dst->init;
$dst->start;
# Attempt to restore - this will fail with the patch because the
# role 'regress_custom_owner' is not included in the dump.
# We check stderr for ERROR messages since psql returns 0 even on SQL errors
# unless ON_ERROR_STOP is set.
my ($ret, $stdout, $stderr) = $dst->psql(
'postgres',
"\\i $dumpfile",
on_error_stop => 0);
# Filter out the expected "role already exists" error for the bootstrap user.
# pg_dumpall emits CREATE ROLE for all roles including the current user,
# which already exists on the destination cluster.
my @errors = grep { !/ERROR: role ".*" already exists/ } split(/\n/, $stderr);
# The restore should complete without any other ERROR messages.
# With the current patch, we expect errors like:
# ERROR: role "regress_custom_owner" does not exist
is(join("\n", @errors), '', 'restore of --schema-only dump produces no unexpected errors');
$dst->stop;
$src->stop;
done_testing();