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

Commit 3f96af4

Browse files
committed
Un-break pg_upgrade from pre-v12 servers.
I neglected to test this scenario while preparing commit f3faf35, so of course it was broken, thanks to some very obscure and undocumented code in pg_dump. Pre-v12 databases might have toast tables attached to partitioned tables, which we need to ignore since newer servers never create such useless toast tables. There was a filter for this case in binary_upgrade_set_type_oids_by_rel_oid(), which appeared to just prevent the pg_type OID from being copied. But actually it managed to prevent the toast table from being created at all --- or it did before I took out that logic. But that was a fundamentally bizarre place to be making the test in the first place. The place where the filter should have been, one would think, is binary_upgrade_set_pg_class_oids(), so add it there. While at it, reorganize binary_upgrade_set_pg_class_oids() so that it doesn't make a completely useless query when it knows it's being invoked for an index. And correct a comment that mis-described the scenario where we need to force creation of a TOAST table. Per buildfarm.
1 parent f3faf35 commit 3f96af4

File tree

1 file changed

+44
-31
lines changed

1 file changed

+44
-31
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4525,43 +4525,56 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
45254525
PQExpBuffer upgrade_buffer, Oid pg_class_oid,
45264526
bool is_index)
45274527
{
4528-
PQExpBuffer upgrade_query = createPQExpBuffer();
4529-
PGresult *upgrade_res;
4530-
Oid pg_class_reltoastrelid;
4531-
Oid pg_index_indexrelid;
4532-
4533-
appendPQExpBuffer(upgrade_query,
4534-
"SELECT c.reltoastrelid, i.indexrelid "
4535-
"FROM pg_catalog.pg_class c LEFT JOIN "
4536-
"pg_catalog.pg_index i ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
4537-
"WHERE c.oid = '%u'::pg_catalog.oid;",
4538-
pg_class_oid);
4539-
4540-
upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
4541-
4542-
pg_class_reltoastrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastrelid")));
4543-
pg_index_indexrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "indexrelid")));
4544-
45454528
appendPQExpBufferStr(upgrade_buffer,
45464529
"\n-- For binary upgrade, must preserve pg_class oids\n");
45474530

45484531
if (!is_index)
45494532
{
4533+
PQExpBuffer upgrade_query = createPQExpBuffer();
4534+
PGresult *upgrade_res;
4535+
Oid pg_class_reltoastrelid;
4536+
char pg_class_relkind;
4537+
Oid pg_index_indexrelid;
4538+
45504539
appendPQExpBuffer(upgrade_buffer,
45514540
"SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
45524541
pg_class_oid);
4553-
/* only tables have toast tables, not indexes */
4554-
if (OidIsValid(pg_class_reltoastrelid))
4555-
{
4556-
/*
4557-
* One complexity is that the table definition might not require
4558-
* the creation of a TOAST table, and the TOAST table might have
4559-
* been created long after table creation, when the table was
4560-
* loaded with wide data. By setting the TOAST oid we force
4561-
* creation of the TOAST heap and TOAST index by the backend so we
4562-
* can cleanly copy the files during binary upgrade.
4563-
*/
45644542

4543+
/*
4544+
* Preserve the OIDs of the table's toast table and index, if any.
4545+
* Indexes cannot have toast tables, so we need not make this probe in
4546+
* the index code path.
4547+
*
4548+
* One complexity is that the current table definition might not
4549+
* require the creation of a TOAST table, but the old database might
4550+
* have a TOAST table that was created earlier, before some wide
4551+
* columns were dropped. By setting the TOAST oid we force creation
4552+
* of the TOAST heap and index by the new backend, so we can copy the
4553+
* files during binary upgrade without worrying about this case.
4554+
*/
4555+
appendPQExpBuffer(upgrade_query,
4556+
"SELECT c.reltoastrelid, c.relkind, i.indexrelid "
4557+
"FROM pg_catalog.pg_class c LEFT JOIN "
4558+
"pg_catalog.pg_index i ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
4559+
"WHERE c.oid = '%u'::pg_catalog.oid;",
4560+
pg_class_oid);
4561+
4562+
upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
4563+
4564+
pg_class_reltoastrelid = atooid(PQgetvalue(upgrade_res, 0,
4565+
PQfnumber(upgrade_res, "reltoastrelid")));
4566+
pg_class_relkind = *PQgetvalue(upgrade_res, 0,
4567+
PQfnumber(upgrade_res, "relkind"));
4568+
pg_index_indexrelid = atooid(PQgetvalue(upgrade_res, 0,
4569+
PQfnumber(upgrade_res, "indexrelid")));
4570+
4571+
/*
4572+
* In a pre-v12 database, partitioned tables might be marked as having
4573+
* toast tables, but we should ignore them if so.
4574+
*/
4575+
if (OidIsValid(pg_class_reltoastrelid) &&
4576+
pg_class_relkind != RELKIND_PARTITIONED_TABLE)
4577+
{
45654578
appendPQExpBuffer(upgrade_buffer,
45664579
"SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
45674580
pg_class_reltoastrelid);
@@ -4571,16 +4584,16 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
45714584
"SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
45724585
pg_index_indexrelid);
45734586
}
4587+
4588+
PQclear(upgrade_res);
4589+
destroyPQExpBuffer(upgrade_query);
45744590
}
45754591
else
45764592
appendPQExpBuffer(upgrade_buffer,
45774593
"SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
45784594
pg_class_oid);
45794595

45804596
appendPQExpBufferChar(upgrade_buffer, '\n');
4581-
4582-
PQclear(upgrade_res);
4583-
destroyPQExpBuffer(upgrade_query);
45844597
}
45854598

45864599
/*

0 commit comments

Comments
 (0)