@@ -3855,8 +3855,8 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
38553855 * getPublications
38563856 * get information about publications
38573857 */
3858- void
3859- getPublications(Archive *fout)
3858+ PublicationInfo *
3859+ getPublications(Archive *fout, int *numPublications )
38603860{
38613861 DumpOptions *dopt = fout->dopt;
38623862 PQExpBuffer query;
@@ -3876,7 +3876,10 @@ getPublications(Archive *fout)
38763876 ntups;
38773877
38783878 if (dopt->no_publications || fout->remoteVersion < 100000)
3879- return;
3879+ {
3880+ *numPublications = 0;
3881+ return NULL;
3882+ }
38803883
38813884 query = createPQExpBuffer();
38823885
@@ -3954,6 +3957,9 @@ getPublications(Archive *fout)
39543957 PQclear(res);
39553958
39563959 destroyPQExpBuffer(query);
3960+
3961+ *numPublications = ntups;
3962+ return pubinfo;
39573963}
39583964
39593965/*
@@ -4062,7 +4068,8 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
40624068 DumpOptions *dopt = fout->dopt;
40634069 int i_tableoid;
40644070 int i_oid;
4065- int i_pubname;
4071+ int i_prpubid;
4072+ int i_prrelid;
40664073 int i,
40674074 j,
40684075 ntups;
@@ -4072,15 +4079,39 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
40724079
40734080 query = createPQExpBuffer();
40744081
4075- for (i = 0; i < numTables; i++)
4082+ /* Collect all publication membership info. */
4083+ appendPQExpBufferStr(query,
4084+ "SELECT tableoid, oid, prpubid, prrelid "
4085+ "FROM pg_catalog.pg_publication_rel");
4086+ res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4087+
4088+ ntups = PQntuples(res);
4089+
4090+ i_tableoid = PQfnumber(res, "tableoid");
4091+ i_oid = PQfnumber(res, "oid");
4092+ i_prpubid = PQfnumber(res, "prpubid");
4093+ i_prrelid = PQfnumber(res, "prrelid");
4094+
4095+ /* this allocation may be more than we need */
4096+ pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4097+ j = 0;
4098+
4099+ for (i = 0; i < ntups; i++)
40764100 {
4077- TableInfo *tbinfo = &tblinfo[i];
4101+ Oid prpubid = atooid(PQgetvalue(res, i, i_prpubid));
4102+ Oid prrelid = atooid(PQgetvalue(res, i, i_prrelid));
4103+ PublicationInfo *pubinfo;
4104+ TableInfo *tbinfo;
40784105
40794106 /*
4080- * Only regular and partitioned tables can be added to publications.
4107+ * Ignore any entries for which we aren't interested in either the
4108+ * publication or the rel.
40814109 */
4082- if (tbinfo->relkind != RELKIND_RELATION &&
4083- tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
4110+ pubinfo = findPublicationByOid(prpubid);
4111+ if (pubinfo == NULL)
4112+ continue;
4113+ tbinfo = findTableByOid(prrelid);
4114+ if (tbinfo == NULL)
40844115 continue;
40854116
40864117 /*
@@ -4090,55 +4121,24 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
40904121 if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
40914122 continue;
40924123
4093- pg_log_info("reading publication membership for table \"%s.%s\"",
4094- tbinfo->dobj.namespace->dobj.name,
4095- tbinfo->dobj.name);
4096-
4097- resetPQExpBuffer(query);
4098-
4099- /* Get the publication membership for the table. */
4100- appendPQExpBuffer(query,
4101- "SELECT pr.tableoid, pr.oid, p.pubname "
4102- "FROM pg_publication_rel pr, pg_publication p "
4103- "WHERE pr.prrelid = '%u'"
4104- " AND p.oid = pr.prpubid",
4105- tbinfo->dobj.catId.oid);
4106- res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4107-
4108- ntups = PQntuples(res);
4109-
4110- if (ntups == 0)
4111- {
4112- /*
4113- * Table is not member of any publications. Clean up and return.
4114- */
4115- PQclear(res);
4116- continue;
4117- }
4118-
4119- i_tableoid = PQfnumber(res, "tableoid");
4120- i_oid = PQfnumber(res, "oid");
4121- i_pubname = PQfnumber(res, "pubname");
4124+ /* OK, make a DumpableObject for this relationship */
4125+ pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4126+ pubrinfo[j].dobj.catId.tableoid =
4127+ atooid(PQgetvalue(res, i, i_tableoid));
4128+ pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
4129+ AssignDumpId(&pubrinfo[j].dobj);
4130+ pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4131+ pubrinfo[j].dobj.name = tbinfo->dobj.name;
4132+ pubrinfo[j].publication = pubinfo;
4133+ pubrinfo[j].pubtable = tbinfo;
41224134
4123- pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
4135+ /* Decide whether we want to dump it */
4136+ selectDumpablePublicationTable(&(pubrinfo[j].dobj), fout);
41244137
4125- for (j = 0; j < ntups; j++)
4126- {
4127- pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
4128- pubrinfo[j].dobj.catId.tableoid =
4129- atooid(PQgetvalue(res, j, i_tableoid));
4130- pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
4131- AssignDumpId(&pubrinfo[j].dobj);
4132- pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
4133- pubrinfo[j].dobj.name = tbinfo->dobj.name;
4134- pubrinfo[j].pubname = pg_strdup(PQgetvalue(res, j, i_pubname));
4135- pubrinfo[j].pubtable = tbinfo;
4136-
4137- /* Decide whether we want to dump it */
4138- selectDumpablePublicationTable(&(pubrinfo[j].dobj), fout);
4139- }
4140- PQclear(res);
4138+ j++;
41414139 }
4140+
4141+ PQclear(res);
41424142 destroyPQExpBuffer(query);
41434143}
41444144
@@ -4149,29 +4149,34 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
41494149static void
41504150dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo)
41514151{
4152+ PublicationInfo *pubinfo = pubrinfo->publication;
41524153 TableInfo *tbinfo = pubrinfo->pubtable;
41534154 PQExpBuffer query;
41544155 char *tag;
41554156
41564157 if (!(pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
41574158 return;
41584159
4159- tag = psprintf("%s %s", pubrinfo->pubname , tbinfo->dobj.name);
4160+ tag = psprintf("%s %s", pubinfo->dobj.name , tbinfo->dobj.name);
41604161
41614162 query = createPQExpBuffer();
41624163
41634164 appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
4164- fmtId(pubrinfo->pubname ));
4165+ fmtId(pubinfo->dobj.name ));
41654166 appendPQExpBuffer(query, " %s;\n",
41664167 fmtQualifiedDumpable(tbinfo));
41674168
41684169 /*
4169- * There is no point in creating drop query as the drop is done by table
4170- * drop.
4170+ * There is no point in creating a drop query as the drop is done by table
4171+ * drop. (If you think to change this, see also _printTocEntry().)
4172+ * Although this object doesn't really have ownership as such, set the
4173+ * owner field anyway to ensure that the command is run by the correct
4174+ * role at restore time.
41714175 */
41724176 ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
41734177 ARCHIVE_OPTS(.tag = tag,
41744178 .namespace = tbinfo->dobj.namespace->dobj.name,
4179+ .owner = pubinfo->rolname,
41754180 .description = "PUBLICATION TABLE",
41764181 .section = SECTION_POST_DATA,
41774182 .createStmt = query->data));
0 commit comments