From 0f955879bf80f6274d0770466e25f87361a46d6b Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Thu, 14 Aug 2025 10:57:59 +0900 Subject: [PATCH v1 06/11] Add support for TOAST chunk_id type in binary upgrades This commit adds a new function, which would set the type of a chunk_id attribute for a TOAST table across upgrades. This piece currently works only with chunk_id = OIDOID, but it is required in a follow-up patch where support for chunk_id = OID8OID is supported on top of the existing one. --- src/include/catalog/binary_upgrade.h | 1 + src/include/catalog/pg_proc.dat | 4 ++++ src/backend/catalog/heap.c | 1 + src/backend/catalog/toasting.c | 20 ++++++++++++++++++- src/backend/utils/adt/pg_upgrade_support.c | 11 ++++++++++ src/bin/pg_dump/pg_dump.c | 10 +++++++++- .../expected/spgist_name_ops.out | 6 ++++-- 7 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/include/catalog/binary_upgrade.h b/src/include/catalog/binary_upgrade.h index 7bf7ae443859..117f3e3f7746 100644 --- a/src/include/catalog/binary_upgrade.h +++ b/src/include/catalog/binary_upgrade.h @@ -29,6 +29,7 @@ extern PGDLLIMPORT Oid binary_upgrade_next_index_pg_class_oid; extern PGDLLIMPORT RelFileNumber binary_upgrade_next_index_pg_class_relfilenumber; extern PGDLLIMPORT Oid binary_upgrade_next_toast_pg_class_oid; extern PGDLLIMPORT RelFileNumber binary_upgrade_next_toast_pg_class_relfilenumber; +extern PGDLLIMPORT Oid binary_upgrade_next_toast_chunk_id_typoid; extern PGDLLIMPORT Oid binary_upgrade_next_pg_enum_oid; extern PGDLLIMPORT Oid binary_upgrade_next_pg_authid_oid; diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index ce49fe25d46e..14ca38e559ea 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -11969,6 +11969,10 @@ proname => 'binary_upgrade_set_next_toast_pg_class_oid', provolatile => 'v', proparallel => 'r', prorettype => 'void', proargtypes => 'oid', prosrc => 'binary_upgrade_set_next_toast_pg_class_oid' }, +{ oid => '8219', descr => 'for use by pg_upgrade', + proname => 'binary_upgrade_set_next_toast_chunk_id_typoid', provolatile => 'v', + proparallel => 'r', prorettype => 'void', proargtypes => 'oid', + prosrc => 'binary_upgrade_set_next_toast_chunk_id_typoid' }, { oid => '3589', descr => 'for use by pg_upgrade', proname => 'binary_upgrade_set_next_pg_enum_oid', provolatile => 'v', proparallel => 'r', prorettype => 'void', proargtypes => 'oid', diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 7678ab13f6a8..866e4cfa835d 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -80,6 +80,7 @@ /* Potentially set by pg_upgrade_support functions */ Oid binary_upgrade_next_heap_pg_class_oid = InvalidOid; Oid binary_upgrade_next_toast_pg_class_oid = InvalidOid; +Oid binary_upgrade_next_toast_chunk_id_typoid = InvalidOid; RelFileNumber binary_upgrade_next_heap_pg_class_relfilenumber = InvalidRelFileNumber; RelFileNumber binary_upgrade_next_toast_pg_class_relfilenumber = InvalidRelFileNumber; diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 4aa52a4bd253..bc0a72268335 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -146,6 +146,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, int16 coloptions[2]; ObjectAddress baseobject, toastobject; + Oid toast_chunkid_typid = OIDOID; /* * Is it already toasted? @@ -184,6 +185,23 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, */ if (!OidIsValid(binary_upgrade_next_toast_pg_class_oid)) return false; + + /* + * The attribute type for chunk_id should have been set when requesting + * a TOAST table creation. + */ + if (!OidIsValid(binary_upgrade_next_toast_chunk_id_typoid)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("toast chunk_id type not set while in binary upgrade mode"))); + if (binary_upgrade_next_toast_chunk_id_typoid != OIDOID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("cannot support toast chunk_id type %u in binary upgrade mode", + binary_upgrade_next_toast_chunk_id_typoid))); + + toast_chunkid_typid = binary_upgrade_next_toast_chunk_id_typoid; + binary_upgrade_next_toast_chunk_id_typoid = InvalidOid; } /* @@ -205,7 +223,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "chunk_id", - OIDOID, + toast_chunkid_typid, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "chunk_seq", diff --git a/src/backend/utils/adt/pg_upgrade_support.c b/src/backend/utils/adt/pg_upgrade_support.c index b505a6b4feeb..06b789d71ded 100644 --- a/src/backend/utils/adt/pg_upgrade_support.c +++ b/src/backend/utils/adt/pg_upgrade_support.c @@ -149,6 +149,17 @@ binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } +Datum +binary_upgrade_set_next_toast_chunk_id_typoid(PG_FUNCTION_ARGS) +{ + Oid typoid = PG_GETARG_OID(0); + + CHECK_IS_BINARY_UPGRADE; + binary_upgrade_next_toast_chunk_id_typoid = typoid; + + PG_RETURN_VOID(); +} + Datum binary_upgrade_set_next_toast_relfilenode(PG_FUNCTION_ARGS) { diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce8..82c2646e793b 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -104,6 +104,7 @@ typedef struct RelFileNumber relfilenumber; /* object filenode */ Oid toast_oid; /* toast table OID */ RelFileNumber toast_relfilenumber; /* toast table filenode */ + Oid toast_chunk_id_typoid; /* type of chunk_id attribute */ Oid toast_index_oid; /* toast table index OID */ RelFileNumber toast_index_relfilenumber; /* toast table index filenode */ } BinaryUpgradeClassOidItem; @@ -5918,7 +5919,10 @@ collectBinaryUpgradeClassOids(Archive *fout) const char *query; query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, " - "ct.relfilenode, i.indexrelid, cti.relfilenode " + "ct.relfilenode, i.indexrelid, cti.relfilenode, " + "(SELECT a.atttypid FROM pg_attribute AS a " + " WHERE a.attrelid = c.reltoastrelid AND attname = 'chunk_id'::text) " + " AS toastchunktypid " "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i " "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) " "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) " @@ -5940,6 +5944,7 @@ collectBinaryUpgradeClassOids(Archive *fout) binaryUpgradeClassOids[i].toast_relfilenumber = atooid(PQgetvalue(res, i, 4)); binaryUpgradeClassOids[i].toast_index_oid = atooid(PQgetvalue(res, i, 5)); binaryUpgradeClassOids[i].toast_index_relfilenumber = atooid(PQgetvalue(res, i, 6)); + binaryUpgradeClassOids[i].toast_chunk_id_typoid = atooid(PQgetvalue(res, i, 7)); } PQclear(res); @@ -6004,6 +6009,9 @@ binary_upgrade_set_pg_class_oids(Archive *fout, appendPQExpBuffer(upgrade_buffer, "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n", entry->toast_relfilenumber); + appendPQExpBuffer(upgrade_buffer, + "SELECT pg_catalog.binary_upgrade_set_next_toast_chunk_id_typoid('%u'::pg_catalog.oid);\n", + entry->toast_chunk_id_typoid); /* every toast table has an index */ appendPQExpBuffer(upgrade_buffer, diff --git a/src/test/modules/spgist_name_ops/expected/spgist_name_ops.out b/src/test/modules/spgist_name_ops/expected/spgist_name_ops.out index 1ee65ede2430..35e59d0cd83c 100644 --- a/src/test/modules/spgist_name_ops/expected/spgist_name_ops.out +++ b/src/test/modules/spgist_name_ops/expected/spgist_name_ops.out @@ -61,9 +61,10 @@ select * from t binary_upgrade_set_next_pg_enum_oid | | binary_upgrade_set_next_pg_enum_oid binary_upgrade_set_next_pg_tablespace_oid | | binary_upgrade_set_next_pg_tablespace_oid binary_upgrade_set_next_pg_type_oid | | binary_upgrade_set_next_pg_type_oid + binary_upgrade_set_next_toast_chunk_id_typoid | | binary_upgrade_set_next_toast_chunk_id_typoid binary_upgrade_set_next_toast_pg_class_oid | 1 | binary_upgrade_set_next_toast_pg_class_oid binary_upgrade_set_next_toast_relfilenode | | binary_upgrade_set_next_toast_relfilenode -(13 rows) +(14 rows) -- Verify clean failure when INCLUDE'd columns result in overlength tuple -- The error message details are platform-dependent, so show only SQLSTATE @@ -110,9 +111,10 @@ select * from t binary_upgrade_set_next_pg_enum_oid | | binary_upgrade_set_next_pg_enum_oid binary_upgrade_set_next_pg_tablespace_oid | | binary_upgrade_set_next_pg_tablespace_oid binary_upgrade_set_next_pg_type_oid | | binary_upgrade_set_next_pg_type_oid + binary_upgrade_set_next_toast_chunk_id_typoid | | binary_upgrade_set_next_toast_chunk_id_typoid binary_upgrade_set_next_toast_pg_class_oid | 1 | binary_upgrade_set_next_toast_pg_class_oid binary_upgrade_set_next_toast_relfilenode | | binary_upgrade_set_next_toast_relfilenode -(13 rows) +(14 rows) \set VERBOSITY sqlstate insert into t values(repeat('xyzzy', 12), 42, repeat('xyzzy', 4000)); -- 2.54.0