Skip to content

Commit 7ac10f6

Browse files
committed
Dump COMMENT ON SCHEMA public.
As we do for other attributes of the public schema, omit the COMMENT command when its payload would match what initdb had installed. For dumps that do carry this new COMMENT command, non-superusers restoring them are likely to get an error. Reviewed by Asif Rehman. Discussion: https://postgr.es/m/ab48a34c-60f6-e388-502a-3e5fe46a2dae@postgresfriends.org
1 parent a7a7be1 commit 7ac10f6

File tree

3 files changed

+79
-20
lines changed

3 files changed

+79
-20
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,15 @@ static NamespaceInfo *findNamespace(Oid nsoid);
169169
static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo);
170170
static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo);
171171
static void guessConstraintInheritance(TableInfo *tblinfo, int numTables);
172-
static void dumpComment(Archive *fout, const char *type, const char *name,
173-
const char *namespace, const char *owner,
174-
CatalogId catalogId, int subid, DumpId dumpId);
172+
static void dumpCommentExtended(Archive *fout, const char *type,
173+
const char *name, const char *namespace,
174+
const char *owner, CatalogId catalogId,
175+
int subid, DumpId dumpId,
176+
const char *initdb_comment);
177+
static inline void dumpComment(Archive *fout, const char *type,
178+
const char *name, const char *namespace,
179+
const char *owner, CatalogId catalogId,
180+
int subid, DumpId dumpId);
175181
static int findComments(Archive *fout, Oid classoid, Oid objoid,
176182
CommentItem **items);
177183
static int collectComments(Archive *fout, CommentItem **items);
@@ -1638,16 +1644,13 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout)
16381644
{
16391645
/*
16401646
* The public schema is a strange beast that sits in a sort of
1641-
* no-mans-land between being a system object and a user object. We
1642-
* don't want to dump creation or comment commands for it, because
1643-
* that complicates matters for non-superuser use of pg_dump. But we
1644-
* should dump any ownership changes, security labels, and ACL
1645-
* changes, and of course we should dump contained objects. pg_dump
1646-
* ties ownership to DUMP_COMPONENT_DEFINITION. Hence, unless the
1647-
* owner is the default, dump a "definition" bearing just a comment.
1647+
* no-mans-land between being a system object and a user object.
1648+
* CREATE SCHEMA would fail, so its DUMP_COMPONENT_DEFINITION is just
1649+
* a comment and an indication of ownership. If the owner is the
1650+
* default, that DUMP_COMPONENT_DEFINITION is superfluous.
16481651
*/
16491652
nsinfo->create = false;
1650-
nsinfo->dobj.dump = DUMP_COMPONENT_ALL & ~DUMP_COMPONENT_COMMENT;
1653+
nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
16511654
if (nsinfo->nspowner == BOOTSTRAP_SUPERUSERID)
16521655
nsinfo->dobj.dump &= ~DUMP_COMPONENT_DEFINITION;
16531656
nsinfo->dobj.dump_contains = DUMP_COMPONENT_ALL;
@@ -9873,7 +9876,7 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
98739876
}
98749877

98759878
/*
9876-
* dumpComment --
9879+
* dumpCommentExtended --
98779880
*
98789881
* This routine is used to dump any comments associated with the
98799882
* object handed to this routine. The routine takes the object type
@@ -9896,9 +9899,11 @@ getDefaultACLs(Archive *fout, int *numDefaultACLs)
98969899
* calling ArchiveEntry() for the specified object.
98979900
*/
98989901
static void
9899-
dumpComment(Archive *fout, const char *type, const char *name,
9900-
const char *namespace, const char *owner,
9901-
CatalogId catalogId, int subid, DumpId dumpId)
9902+
dumpCommentExtended(Archive *fout, const char *type,
9903+
const char *name, const char *namespace,
9904+
const char *owner, CatalogId catalogId,
9905+
int subid, DumpId dumpId,
9906+
const char *initdb_comment)
99029907
{
99039908
DumpOptions *dopt = fout->dopt;
99049909
CommentItem *comments;
@@ -9934,6 +9939,25 @@ dumpComment(Archive *fout, const char *type, const char *name,
99349939
ncomments--;
99359940
}
99369941

9942+
if (initdb_comment != NULL)
9943+
{
9944+
static CommentItem empty_comment = {.descr = ""};
9945+
9946+
/*
9947+
* initdb creates this object with a comment. Skip dumping the
9948+
* initdb-provided comment, which would complicate matters for
9949+
* non-superuser use of pg_dump. When the DBA has removed initdb's
9950+
* comment, replicate that.
9951+
*/
9952+
if (ncomments == 0)
9953+
{
9954+
comments = &empty_comment;
9955+
ncomments = 1;
9956+
}
9957+
else if (strcmp(comments->descr, initdb_comment) == 0)
9958+
ncomments = 0;
9959+
}
9960+
99379961
/* If a comment exists, build COMMENT ON statement */
99389962
if (ncomments > 0)
99399963
{
@@ -9969,6 +9993,21 @@ dumpComment(Archive *fout, const char *type, const char *name,
99699993
}
99709994
}
99719995

9996+
/*
9997+
* dumpComment --
9998+
*
9999+
* Typical simplification of the above function.
10000+
*/
10001+
static inline void
10002+
dumpComment(Archive *fout, const char *type,
10003+
const char *name, const char *namespace,
10004+
const char *owner, CatalogId catalogId,
10005+
int subid, DumpId dumpId)
10006+
{
10007+
dumpCommentExtended(fout, type, name, namespace, owner,
10008+
catalogId, subid, dumpId, NULL);
10009+
}
10010+
997210011
/*
997310012
* dumpTableComment --
997410013
*
@@ -10426,9 +10465,18 @@ dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
1042610465

1042710466
/* Dump Schema Comments and Security Labels */
1042810467
if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
10429-
dumpComment(fout, "SCHEMA", qnspname,
10430-
NULL, nspinfo->rolname,
10431-
nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
10468+
{
10469+
const char *initdb_comment = NULL;
10470+
10471+
if (!nspinfo->create && strcmp(qnspname, "public") == 0)
10472+
initdb_comment = (fout->remoteVersion >= 80300 ?
10473+
"standard public schema" :
10474+
"Standard public schema");
10475+
dumpCommentExtended(fout, "SCHEMA", qnspname,
10476+
NULL, nspinfo->rolname,
10477+
nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
10478+
initdb_comment);
10479+
}
1043210480

1043310481
if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
1043410482
dumpSecLabel(fout, "SCHEMA", qnspname,

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -983,9 +983,19 @@
983983

984984
'COMMENT ON SCHEMA public' => {
985985
regexp => qr/^COMMENT ON SCHEMA public IS .+;/m,
986+
# regress_public_owner emits this, due to create_sql of next test
987+
like => {
988+
pg_dumpall_dbprivs => 1,
989+
pg_dumpall_exclude => 1,
990+
},
991+
},
986992

987-
# this shouldn't ever get emitted
988-
like => {},
993+
'COMMENT ON SCHEMA public IS NULL' => {
994+
database => 'regress_public_owner',
995+
create_order => 100,
996+
create_sql => 'COMMENT ON SCHEMA public IS NULL;',
997+
regexp => qr/^COMMENT ON SCHEMA public IS '';/m,
998+
like => { defaults_public_owner => 1 },
989999
},
9901000

9911001
'COMMENT ON TABLE dump_test.test_table' => {

src/include/catalog/pg_namespace.dat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
{ oid => '99', oid_symbol => 'PG_TOAST_NAMESPACE',
1919
descr => 'reserved schema for TOAST tables',
2020
nspname => 'pg_toast', nspacl => '_null_' },
21+
# update dumpNamespace() if changing this descr
2122
{ oid => '2200', oid_symbol => 'PG_PUBLIC_NAMESPACE',
2223
descr => 'standard public schema',
2324
nspname => 'public', nspacl => '_null_' },

0 commit comments

Comments
 (0)