Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0d221ec

Browse files
committed
pg_dump: label PUBLICATION TABLE ArchiveEntries with an owner.
This is the same fix as commit 9eabfe3 applied to INDEX ATTACH entries, but for table-to-publication attachments. As in that case, even though the backend doesn't record "ownership" of the attachment, we still ought to label it in the dump archive with the role name that should run the ALTER PUBLICATION command. The existing behavior causes the ALTER to be done by the original role that started the restore; that will usually work fine, but there may be corner cases where it fails. The bulk of the patch is concerned with changing struct PublicationRelInfo to include a pointer to the associated PublicationInfo object, so that we can get the owner's name out of that when the time comes. While at it, I rewrote getPublicationTables() to do just one query of pg_publication_rel, not one per table. Back-patch to v10 where this code was introduced. Discussion: https://postgr.es/m/1165710.1610473242@sss.pgh.pa.us
1 parent c9b7025 commit 0d221ec

File tree

3 files changed

+87
-61
lines changed

3 files changed

+87
-61
lines changed

src/bin/pg_dump/common.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@ static DumpableObject **oprinfoindex;
5454
static DumpableObject **collinfoindex;
5555
static DumpableObject **nspinfoindex;
5656
static DumpableObject **extinfoindex;
57+
static DumpableObject **pubinfoindex;
5758
static int numTables;
5859
static int numTypes;
5960
static int numFuncs;
6061
static int numOperators;
6162
static int numCollations;
6263
static int numNamespaces;
6364
static int numExtensions;
65+
static int numPublications;
6466

6567
/* This is an array of object identities, not actual DumpableObjects */
6668
static ExtensionMemberId *extmembers;
@@ -95,6 +97,7 @@ getSchemaData(Archive *fout, int *numTablesPtr)
9597
CollInfo *collinfo;
9698
NamespaceInfo *nspinfo;
9799
ExtensionInfo *extinfo;
100+
PublicationInfo *pubinfo;
98101
InhInfo *inhinfo;
99102
int numAggregates;
100103
int numInherits;
@@ -249,7 +252,9 @@ getSchemaData(Archive *fout, int *numTablesPtr)
249252
getPolicies(fout, tblinfo, numTables);
250253

251254
pg_log_info("reading publications");
252-
getPublications(fout);
255+
pubinfo = getPublications(fout, &numPublications);
256+
pubinfoindex = buildIndexArray(pubinfo, numPublications,
257+
sizeof(PublicationInfo));
253258

254259
pg_log_info("reading publication membership");
255260
getPublicationTables(fout, tblinfo, numTables);
@@ -899,6 +904,17 @@ findExtensionByOid(Oid oid)
899904
return (ExtensionInfo *) findObjectByOid(oid, extinfoindex, numExtensions);
900905
}
901906

907+
/*
908+
* findPublicationByOid
909+
* finds the entry (in pubinfo) of the publication with the given oid
910+
* returns NULL if not found
911+
*/
912+
PublicationInfo *
913+
findPublicationByOid(Oid oid)
914+
{
915+
return (PublicationInfo *) findObjectByOid(oid, pubinfoindex, numPublications);
916+
}
917+
902918
/*
903919
* findIndexByOid
904920
* find the entry of the index with the given oid

src/bin/pg_dump/pg_dump.c

Lines changed: 66 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3785,8 +3785,8 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
37853785
* getPublications
37863786
* get information about publications
37873787
*/
3788-
void
3789-
getPublications(Archive *fout)
3788+
PublicationInfo *
3789+
getPublications(Archive *fout, int *numPublications)
37903790
{
37913791
DumpOptions *dopt = fout->dopt;
37923792
PQExpBuffer query;
@@ -3805,7 +3805,10 @@ getPublications(Archive *fout)
38053805
ntups;
38063806

38073807
if (dopt->no_publications || fout->remoteVersion < 100000)
3808-
return;
3808+
{
3809+
*numPublications = 0;
3810+
return NULL;
3811+
}
38093812

38103813
query = createPQExpBuffer();
38113814

@@ -3873,6 +3876,9 @@ getPublications(Archive *fout)
38733876
PQclear(res);
38743877

38753878
destroyPQExpBuffer(query);
3879+
3880+
*numPublications = ntups;
3881+
return pubinfo;
38763882
}
38773883

38783884
/*
@@ -3976,7 +3982,8 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
39763982
DumpOptions *dopt = fout->dopt;
39773983
int i_tableoid;
39783984
int i_oid;
3979-
int i_pubname;
3985+
int i_prpubid;
3986+
int i_prrelid;
39803987
int i,
39813988
j,
39823989
ntups;
@@ -3986,12 +3993,39 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
39863993

39873994
query = createPQExpBuffer();
39883995

3989-
for (i = 0; i < numTables; i++)
3996+
/* Collect all publication membership info. */
3997+
appendPQExpBufferStr(query,
3998+
"SELECT tableoid, oid, prpubid, prrelid "
3999+
"FROM pg_catalog.pg_publication_rel");
4000+
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4001+
4002+
ntups = PQntuples(res);
4003+
4004+
i_tableoid = PQfnumber(res, "tableoid");
4005+
i_oid = PQfnumber(res, "oid");
4006+
i_prpubid = PQfnumber(res, "prpubid");
4007+
i_prrelid = PQfnumber(res, "prrelid");
4008+
4009+
/* this allocation may be more than we need */
4010+
pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4011+
j = 0;
4012+
4013+
for (i = 0; i < ntups; i++)
39904014
{
3991-
TableInfo *tbinfo = &tblinfo[i];
4015+
Oid prpubid = atooid(PQgetvalue(res, i, i_prpubid));
4016+
Oid prrelid = atooid(PQgetvalue(res, i, i_prrelid));
4017+
PublicationInfo *pubinfo;
4018+
TableInfo *tbinfo;
39924019

3993-
/* Only plain tables can be aded to publications. */
3994-
if (tbinfo->relkind != RELKIND_RELATION)
4020+
/*
4021+
* Ignore any entries for which we aren't interested in either the
4022+
* publication or the rel.
4023+
*/
4024+
pubinfo = findPublicationByOid(prpubid);
4025+
if (pubinfo == NULL)
4026+
continue;
4027+
tbinfo = findTableByOid(prrelid);
4028+
if (tbinfo == NULL)
39954029
continue;
39964030

39974031
/*
@@ -4001,55 +4035,24 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
40014035
if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
40024036
continue;
40034037

4004-
pg_log_info("reading publication membership for table \"%s.%s\"",
4005-
tbinfo->dobj.namespace->dobj.name,
4006-
tbinfo->dobj.name);
4007-
4008-
resetPQExpBuffer(query);
4009-
4010-
/* Get the publication membership for the table. */
4011-
appendPQExpBuffer(query,
4012-
"SELECT pr.tableoid, pr.oid, p.pubname "
4013-
"FROM pg_publication_rel pr, pg_publication p "
4014-
"WHERE pr.prrelid = '%u'"
4015-
" AND p.oid = pr.prpubid",
4016-
tbinfo->dobj.catId.oid);
4017-
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4018-
4019-
ntups = PQntuples(res);
4020-
4021-
if (ntups == 0)
4022-
{
4023-
/*
4024-
* Table is not member of any publications. Clean up and return.
4025-
*/
4026-
PQclear(res);
4027-
continue;
4028-
}
4029-
4030-
i_tableoid = PQfnumber(res, "tableoid");
4031-
i_oid = PQfnumber(res, "oid");
4032-
i_pubname = PQfnumber(res, "pubname");
4038+
/* OK, make a DumpableObject for this relationship */
4039+
pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4040+
pubrinfo[j].dobj.catId.tableoid =
4041+
atooid(PQgetvalue(res, i, i_tableoid));
4042+
pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4043+
AssignDumpId(&pubrinfo[j].dobj);
4044+
pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4045+
pubrinfo[j].dobj.name = tbinfo->dobj.name;
4046+
pubrinfo[j].publication = pubinfo;
4047+
pubrinfo[j].pubtable = tbinfo;
40334048

4034-
pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4049+
/* Decide whether we want to dump it */
4050+
selectDumpablePublicationTable(&(pubrinfo[j].dobj), fout);
40354051

4036-
for (j = 0; j < ntups; j++)
4037-
{
4038-
pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4039-
pubrinfo[j].dobj.catId.tableoid =
4040-
atooid(PQgetvalue(res, j, i_tableoid));
4041-
pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
4042-
AssignDumpId(&pubrinfo[j].dobj);
4043-
pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4044-
pubrinfo[j].dobj.name = tbinfo->dobj.name;
4045-
pubrinfo[j].pubname = pg_strdup(PQgetvalue(res, j, i_pubname));
4046-
pubrinfo[j].pubtable = tbinfo;
4047-
4048-
/* Decide whether we want to dump it */
4049-
selectDumpablePublicationTable(&(pubrinfo[j].dobj), fout);
4050-
}
4051-
PQclear(res);
4052+
j++;
40524053
}
4054+
4055+
PQclear(res);
40534056
destroyPQExpBuffer(query);
40544057
}
40554058

@@ -4060,29 +4063,34 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
40604063
static void
40614064
dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo)
40624065
{
4066+
PublicationInfo *pubinfo = pubrinfo->publication;
40634067
TableInfo *tbinfo = pubrinfo->pubtable;
40644068
PQExpBuffer query;
40654069
char *tag;
40664070

40674071
if (!(pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
40684072
return;
40694073

4070-
tag = psprintf("%s %s", pubrinfo->pubname, tbinfo->dobj.name);
4074+
tag = psprintf("%s %s", pubinfo->dobj.name, tbinfo->dobj.name);
40714075

40724076
query = createPQExpBuffer();
40734077

40744078
appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
4075-
fmtId(pubrinfo->pubname));
4079+
fmtId(pubinfo->dobj.name));
40764080
appendPQExpBuffer(query, " %s;\n",
40774081
fmtQualifiedDumpable(tbinfo));
40784082

40794083
/*
4080-
* There is no point in creating drop query as the drop is done by table
4081-
* drop.
4084+
* There is no point in creating a drop query as the drop is done by table
4085+
* drop. (If you think to change this, see also _printTocEntry().)
4086+
* Although this object doesn't really have ownership as such, set the
4087+
* owner field anyway to ensure that the command is run by the correct
4088+
* role at restore time.
40824089
*/
40834090
ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
40844091
ARCHIVE_OPTS(.tag = tag,
40854092
.namespace = tbinfo->dobj.namespace->dobj.name,
4093+
.owner = pubinfo->rolname,
40864094
.description = "PUBLICATION TABLE",
40874095
.section = SECTION_POST_DATA,
40884096
.createStmt = query->data));

src/bin/pg_dump/pg_dump.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -613,8 +613,8 @@ typedef struct _PublicationInfo
613613
typedef struct _PublicationRelInfo
614614
{
615615
DumpableObject dobj;
616+
PublicationInfo *publication;
616617
TableInfo *pubtable;
617-
char *pubname;
618618
} PublicationRelInfo;
619619

620620
/*
@@ -672,6 +672,7 @@ extern OprInfo *findOprByOid(Oid oid);
672672
extern CollInfo *findCollationByOid(Oid oid);
673673
extern NamespaceInfo *findNamespaceByOid(Oid oid);
674674
extern ExtensionInfo *findExtensionByOid(Oid oid);
675+
extern PublicationInfo *findPublicationByOid(Oid oid);
675676

676677
extern void setExtensionMembership(ExtensionMemberId *extmems, int nextmems);
677678
extern ExtensionInfo *findOwningExtension(CatalogId catalogId);
@@ -724,7 +725,8 @@ extern void processExtensionTables(Archive *fout, ExtensionInfo extinfo[],
724725
int numExtensions);
725726
extern EventTriggerInfo *getEventTriggers(Archive *fout, int *numEventTriggers);
726727
extern void getPolicies(Archive *fout, TableInfo tblinfo[], int numTables);
727-
extern void getPublications(Archive *fout);
728+
extern PublicationInfo *getPublications(Archive *fout,
729+
int *numPublications);
728730
extern void getPublicationTables(Archive *fout, TableInfo tblinfo[],
729731
int numTables);
730732
extern void getSubscriptions(Archive *fout);

0 commit comments

Comments
 (0)