5555#include "catalog/pg_trigger_d.h"
5656#include "catalog/pg_type_d.h"
5757#include "common/connect.h"
58+ #include "common/int.h"
5859#include "common/relpath.h"
5960#include "compress_io.h"
6061#include "dumputils.h"
@@ -92,6 +93,17 @@ typedef struct
9293 int objsubid; /* subobject (table column #) */
9394} SecLabelItem;
9495
96+ typedef struct
97+ {
98+ Oid oid; /* object OID */
99+ char relkind; /* object kind */
100+ RelFileNumber relfilenumber; /* object filenode */
101+ Oid toast_oid; /* toast table OID */
102+ RelFileNumber toast_relfilenumber; /* toast table filenode */
103+ Oid toast_index_oid; /* toast table index OID */
104+ RelFileNumber toast_index_relfilenumber; /* toast table index filenode */
105+ } BinaryUpgradeClassOidItem;
106+
95107typedef enum OidOptions
96108{
97109 zeroIsError = 1,
@@ -157,6 +169,10 @@ static int ncomments = 0;
157169static SecLabelItem *seclabels = NULL;
158170static int nseclabels = 0;
159171
172+ /* sorted table of pg_class information for binary upgrade */
173+ static BinaryUpgradeClassOidItem *binaryUpgradeClassOids = NULL;
174+ static int nbinaryUpgradeClassOids = 0;
175+
160176/*
161177 * The default number of rows per INSERT when
162178 * --inserts is specified without --rows-per-insert
@@ -322,6 +338,7 @@ static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
322338static void binary_upgrade_set_type_oids_by_rel(Archive *fout,
323339 PQExpBuffer upgrade_buffer,
324340 const TableInfo *tbinfo);
341+ static void collectBinaryUpgradeClassOids(Archive *fout);
325342static void binary_upgrade_set_pg_class_oids(Archive *fout,
326343 PQExpBuffer upgrade_buffer,
327344 Oid pg_class_oid);
@@ -971,6 +988,10 @@ main(int argc, char **argv)
971988 if (!dopt.no_security_labels)
972989 collectSecLabels(fout);
973990
991+ /* For binary upgrade mode, collect required pg_class information. */
992+ if (dopt.binary_upgrade)
993+ collectBinaryUpgradeClassOids(fout);
994+
974995 /* Lastly, create dummy objects to represent the section boundaries */
975996 boundaryObjs = createBoundaryObjects();
976997
@@ -5383,18 +5404,67 @@ binary_upgrade_set_type_oids_by_rel(Archive *fout,
53835404 pg_type_oid, false, false);
53845405}
53855406
5407+ /*
5408+ * bsearch() comparator for BinaryUpgradeClassOidItem
5409+ */
5410+ static int
5411+ BinaryUpgradeClassOidItemCmp(const void *p1, const void *p2)
5412+ {
5413+ BinaryUpgradeClassOidItem v1 = *((const BinaryUpgradeClassOidItem *) p1);
5414+ BinaryUpgradeClassOidItem v2 = *((const BinaryUpgradeClassOidItem *) p2);
5415+
5416+ return pg_cmp_u32(v1.oid, v2.oid);
5417+ }
5418+
5419+ /*
5420+ * collectBinaryUpgradeClassOids
5421+ *
5422+ * Construct a table of pg_class information required for
5423+ * binary_upgrade_set_pg_class_oids(). The table is sorted by OID for speed in
5424+ * lookup.
5425+ */
5426+ static void
5427+ collectBinaryUpgradeClassOids(Archive *fout)
5428+ {
5429+ PGresult *res;
5430+ const char *query;
5431+
5432+ query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
5433+ "ct.relfilenode, i.indexrelid, cti.relfilenode "
5434+ "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
5435+ "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5436+ "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5437+ "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5438+ "ORDER BY c.oid;";
5439+
5440+ res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
5441+
5442+ nbinaryUpgradeClassOids = PQntuples(res);
5443+ binaryUpgradeClassOids = (BinaryUpgradeClassOidItem *)
5444+ pg_malloc(nbinaryUpgradeClassOids * sizeof(BinaryUpgradeClassOidItem));
5445+
5446+ for (int i = 0; i < nbinaryUpgradeClassOids; i++)
5447+ {
5448+ binaryUpgradeClassOids[i].oid = atooid(PQgetvalue(res, i, 0));
5449+ binaryUpgradeClassOids[i].relkind = *PQgetvalue(res, i, 1);
5450+ binaryUpgradeClassOids[i].relfilenumber = atooid(PQgetvalue(res, i, 2));
5451+ binaryUpgradeClassOids[i].toast_oid = atooid(PQgetvalue(res, i, 3));
5452+ binaryUpgradeClassOids[i].toast_relfilenumber = atooid(PQgetvalue(res, i, 4));
5453+ binaryUpgradeClassOids[i].toast_index_oid = atooid(PQgetvalue(res, i, 5));
5454+ binaryUpgradeClassOids[i].toast_index_relfilenumber = atooid(PQgetvalue(res, i, 6));
5455+ }
5456+
5457+ PQclear(res);
5458+ }
5459+
53865460static void
53875461binary_upgrade_set_pg_class_oids(Archive *fout,
53885462 PQExpBuffer upgrade_buffer, Oid pg_class_oid)
53895463{
5390- PQExpBuffer upgrade_query = createPQExpBuffer();
5391- PGresult *upgrade_res;
5392- RelFileNumber relfilenumber;
5393- Oid toast_oid;
5394- RelFileNumber toast_relfilenumber;
5395- char relkind;
5396- Oid toast_index_oid;
5397- RelFileNumber toast_index_relfilenumber;
5464+ BinaryUpgradeClassOidItem key = {0};
5465+ BinaryUpgradeClassOidItem *entry;
5466+
5467+ Assert(binaryUpgradeClassOids);
53985468
53995469 /*
54005470 * Preserve the OID and relfilenumber of the table, table's index, table's
@@ -5407,35 +5477,16 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
54075477 * by the new backend, so we can copy the files during binary upgrade
54085478 * without worrying about this case.
54095479 */
5410- appendPQExpBuffer(upgrade_query,
5411- "SELECT c.relkind, c.relfilenode, c.reltoastrelid, ct.relfilenode AS toast_relfilenode, i.indexrelid, cti.relfilenode AS toast_index_relfilenode "
5412- "FROM pg_catalog.pg_class c LEFT JOIN "
5413- "pg_catalog.pg_index i ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
5414- "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
5415- "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
5416- "WHERE c.oid = '%u'::pg_catalog.oid;",
5417- pg_class_oid);
5418-
5419- upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
5420-
5421- relkind = *PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "relkind"));
5422-
5423- relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
5424- PQfnumber(upgrade_res, "relfilenode")));
5425- toast_oid = atooid(PQgetvalue(upgrade_res, 0,
5426- PQfnumber(upgrade_res, "reltoastrelid")));
5427- toast_relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
5428- PQfnumber(upgrade_res, "toast_relfilenode")));
5429- toast_index_oid = atooid(PQgetvalue(upgrade_res, 0,
5430- PQfnumber(upgrade_res, "indexrelid")));
5431- toast_index_relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
5432- PQfnumber(upgrade_res, "toast_index_relfilenode")));
5480+ key.oid = pg_class_oid;
5481+ entry = bsearch(&key, binaryUpgradeClassOids, nbinaryUpgradeClassOids,
5482+ sizeof(BinaryUpgradeClassOidItem),
5483+ BinaryUpgradeClassOidItemCmp);
54335484
54345485 appendPQExpBufferStr(upgrade_buffer,
54355486 "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
54365487
5437- if (relkind != RELKIND_INDEX &&
5438- relkind != RELKIND_PARTITIONED_INDEX)
5488+ if (entry-> relkind != RELKIND_INDEX &&
5489+ entry-> relkind != RELKIND_PARTITIONED_INDEX)
54395490 {
54405491 appendPQExpBuffer(upgrade_buffer,
54415492 "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
@@ -5446,32 +5497,33 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
54465497 * partitioned tables have a relfilenumber, which should not be
54475498 * preserved when upgrading.
54485499 */
5449- if (RelFileNumberIsValid(relfilenumber) && relkind != RELKIND_PARTITIONED_TABLE)
5500+ if (RelFileNumberIsValid(entry->relfilenumber) &&
5501+ entry->relkind != RELKIND_PARTITIONED_TABLE)
54505502 appendPQExpBuffer(upgrade_buffer,
54515503 "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
5452- relfilenumber);
5504+ entry-> relfilenumber);
54535505
54545506 /*
54555507 * In a pre-v12 database, partitioned tables might be marked as having
54565508 * toast tables, but we should ignore them if so.
54575509 */
5458- if (OidIsValid(toast_oid) &&
5459- relkind != RELKIND_PARTITIONED_TABLE)
5510+ if (OidIsValid(entry-> toast_oid) &&
5511+ entry-> relkind != RELKIND_PARTITIONED_TABLE)
54605512 {
54615513 appendPQExpBuffer(upgrade_buffer,
54625514 "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
5463- toast_oid);
5515+ entry-> toast_oid);
54645516 appendPQExpBuffer(upgrade_buffer,
54655517 "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
5466- toast_relfilenumber);
5518+ entry-> toast_relfilenumber);
54675519
54685520 /* every toast table has an index */
54695521 appendPQExpBuffer(upgrade_buffer,
54705522 "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
5471- toast_index_oid);
5523+ entry-> toast_index_oid);
54725524 appendPQExpBuffer(upgrade_buffer,
54735525 "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5474- toast_index_relfilenumber);
5526+ entry-> toast_index_relfilenumber);
54755527 }
54765528 }
54775529 else
@@ -5482,14 +5534,10 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
54825534 pg_class_oid);
54835535 appendPQExpBuffer(upgrade_buffer,
54845536 "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
5485- relfilenumber);
5537+ entry-> relfilenumber);
54865538 }
54875539
5488- PQclear(upgrade_res);
5489-
54905540 appendPQExpBufferChar(upgrade_buffer, '\n');
5491-
5492- destroyPQExpBuffer(upgrade_query);
54935541}
54945542
54955543/*
0 commit comments