@@ -3865,8 +3865,8 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
38653865 * getPublications
38663866 * get information about publications
38673867 */
3868- void
3869- getPublications(Archive *fout)
3868+ PublicationInfo *
3869+ getPublications(Archive *fout, int *numPublications )
38703870{
38713871 DumpOptions *dopt = fout->dopt;
38723872 PQExpBuffer query;
@@ -3886,7 +3886,10 @@ getPublications(Archive *fout)
38863886 ntups;
38873887
38883888 if (dopt->no_publications || fout->remoteVersion < 100000)
3889- return;
3889+ {
3890+ *numPublications = 0;
3891+ return NULL;
3892+ }
38903893
38913894 query = createPQExpBuffer();
38923895
@@ -3964,6 +3967,9 @@ getPublications(Archive *fout)
39643967 PQclear(res);
39653968
39663969 destroyPQExpBuffer(query);
3970+
3971+ *numPublications = ntups;
3972+ return pubinfo;
39673973}
39683974
39693975/*
@@ -4072,7 +4078,8 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
40724078 DumpOptions *dopt = fout->dopt;
40734079 int i_tableoid;
40744080 int i_oid;
4075- int i_pubname;
4081+ int i_prpubid;
4082+ int i_prrelid;
40764083 int i,
40774084 j,
40784085 ntups;
@@ -4082,15 +4089,39 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
40824089
40834090 query = createPQExpBuffer();
40844091
4085- for (i = 0; i < numTables; i++)
4092+ /* Collect all publication membership info. */
4093+ appendPQExpBufferStr(query,
4094+ "SELECT tableoid, oid, prpubid, prrelid "
4095+ "FROM pg_catalog.pg_publication_rel");
4096+ res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4097+
4098+ ntups = PQntuples(res);
4099+
4100+ i_tableoid = PQfnumber(res, "tableoid");
4101+ i_oid = PQfnumber(res, "oid");
4102+ i_prpubid = PQfnumber(res, "prpubid");
4103+ i_prrelid = PQfnumber(res, "prrelid");
4104+
4105+ /* this allocation may be more than we need */
4106+ pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4107+ j = 0;
4108+
4109+ for (i = 0; i < ntups; i++)
40864110 {
4087- TableInfo *tbinfo = &tblinfo[i];
4111+ Oid prpubid = atooid(PQgetvalue(res, i, i_prpubid));
4112+ Oid prrelid = atooid(PQgetvalue(res, i, i_prrelid));
4113+ PublicationInfo *pubinfo;
4114+ TableInfo *tbinfo;
40884115
40894116 /*
4090- * Only regular and partitioned tables can be added to publications.
4117+ * Ignore any entries for which we aren't interested in either the
4118+ * publication or the rel.
40914119 */
4092- if (tbinfo->relkind != RELKIND_RELATION &&
4093- tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
4120+ pubinfo = findPublicationByOid(prpubid);
4121+ if (pubinfo == NULL)
4122+ continue;
4123+ tbinfo = findTableByOid(prrelid);
4124+ if (tbinfo == NULL)
40944125 continue;
40954126
40964127 /*
@@ -4100,55 +4131,24 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
41004131 if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
41014132 continue;
41024133
4103- pg_log_info("reading publication membership for table \"%s.%s\"",
4104- tbinfo->dobj.namespace->dobj.name,
4105- tbinfo->dobj.name);
4106-
4107- resetPQExpBuffer(query);
4108-
4109- /* Get the publication membership for the table. */
4110- appendPQExpBuffer(query,
4111- "SELECT pr.tableoid, pr.oid, p.pubname "
4112- "FROM pg_publication_rel pr, pg_publication p "
4113- "WHERE pr.prrelid = '%u'"
4114- " AND p.oid = pr.prpubid",
4115- tbinfo->dobj.catId.oid);
4116- res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4117-
4118- ntups = PQntuples(res);
4119-
4120- if (ntups == 0)
4121- {
4122- /*
4123- * Table is not member of any publications. Clean up and return.
4124- */
4125- PQclear(res);
4126- continue;
4127- }
4128-
4129- i_tableoid = PQfnumber(res, "tableoid");
4130- i_oid = PQfnumber(res, "oid");
4131- i_pubname = PQfnumber(res, "pubname");
4134+ /* OK, make a DumpableObject for this relationship */
4135+ pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4136+ pubrinfo[j].dobj.catId.tableoid =
4137+ atooid(PQgetvalue(res, i, i_tableoid));
4138+ pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4139+ AssignDumpId(&pubrinfo[j].dobj);
4140+ pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4141+ pubrinfo[j].dobj.name = tbinfo->dobj.name;
4142+ pubrinfo[j].publication = pubinfo;
4143+ pubrinfo[j].pubtable = tbinfo;
41324144
4133- pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4145+ /* Decide whether we want to dump it */
4146+ selectDumpablePublicationTable(&(pubrinfo[j].dobj), fout);
41344147
4135- for (j = 0; j < ntups; j++)
4136- {
4137- pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4138- pubrinfo[j].dobj.catId.tableoid =
4139- atooid(PQgetvalue(res, j, i_tableoid));
4140- pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
4141- AssignDumpId(&pubrinfo[j].dobj);
4142- pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4143- pubrinfo[j].dobj.name = tbinfo->dobj.name;
4144- pubrinfo[j].pubname = pg_strdup(PQgetvalue(res, j, i_pubname));
4145- pubrinfo[j].pubtable = tbinfo;
4146-
4147- /* Decide whether we want to dump it */
4148- selectDumpablePublicationTable(&(pubrinfo[j].dobj), fout);
4149- }
4150- PQclear(res);
4148+ j++;
41514149 }
4150+
4151+ PQclear(res);
41524152 destroyPQExpBuffer(query);
41534153}
41544154
@@ -4159,29 +4159,34 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
41594159static void
41604160dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo)
41614161{
4162+ PublicationInfo *pubinfo = pubrinfo->publication;
41624163 TableInfo *tbinfo = pubrinfo->pubtable;
41634164 PQExpBuffer query;
41644165 char *tag;
41654166
41664167 if (!(pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
41674168 return;
41684169
4169- tag = psprintf("%s %s", pubrinfo->pubname , tbinfo->dobj.name);
4170+ tag = psprintf("%s %s", pubinfo->dobj.name , tbinfo->dobj.name);
41704171
41714172 query = createPQExpBuffer();
41724173
41734174 appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
4174- fmtId(pubrinfo->pubname ));
4175+ fmtId(pubinfo->dobj.name ));
41754176 appendPQExpBuffer(query, " %s;\n",
41764177 fmtQualifiedDumpable(tbinfo));
41774178
41784179 /*
4179- * There is no point in creating drop query as the drop is done by table
4180- * drop.
4180+ * There is no point in creating a drop query as the drop is done by table
4181+ * drop. (If you think to change this, see also _printTocEntry().)
4182+ * Although this object doesn't really have ownership as such, set the
4183+ * owner field anyway to ensure that the command is run by the correct
4184+ * role at restore time.
41814185 */
41824186 ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
41834187 ARCHIVE_OPTS(.tag = tag,
41844188 .namespace = tbinfo->dobj.namespace->dobj.name,
4189+ .owner = pubinfo->rolname,
41854190 .description = "PUBLICATION TABLE",
41864191 .section = SECTION_POST_DATA,
41874192 .createStmt = query->data));
0 commit comments