Skip to content

Commit 590a870

Browse files
committed
Ignore attempts to add TOAST table to shared or catalog tables
Running ALTER TABLE on any table will check if a TOAST table needs to be added. On shared tables, this would previously fail, thus effectively disabling ALTER TABLE for those tables. On (non-shared) system catalogs, on the other hand, it would add a TOAST table, even though we don't really want TOAST tables on some system catalogs. In some cases, it would also fail with an error "AccessExclusiveLock required to add toast table.", depending on what locks the ALTER TABLE actions had already taken. So instead, just ignore attempts to add TOAST tables to such tables, outside of bootstrap mode, pretending they don't need one. This allows running ALTER TABLE on such tables without messing up the TOAST situation. Legitimate uses for ALTER TABLE on system catalogs include setting reloptions (say, fillfactor or autovacuum settings). (All this still requires allow_system_table_mods, which is independent of this.) Discussion: https://www.postgresql.org/message-id/flat/[email protected]
1 parent e537ac5 commit 590a870

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

src/backend/catalog/toasting.c

+26-16
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "access/tuptoaster.h"
1919
#include "access/xact.h"
2020
#include "catalog/binary_upgrade.h"
21+
#include "catalog/catalog.h"
2122
#include "catalog/dependency.h"
2223
#include "catalog/heap.h"
2324
#include "catalog/index.h"
@@ -146,21 +147,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
146147
ObjectAddress baseobject,
147148
toastobject;
148149

149-
/*
150-
* Toast table is shared if and only if its parent is.
151-
*
152-
* We cannot allow toasting a shared relation after initdb (because
153-
* there's no way to mark it toasted in other databases' pg_class).
154-
*/
155-
shared_relation = rel->rd_rel->relisshared;
156-
if (shared_relation && !IsBootstrapProcessingMode())
157-
ereport(ERROR,
158-
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
159-
errmsg("shared tables cannot be toasted after initdb")));
160-
161-
/* It's mapped if and only if its parent is, too */
162-
mapped_relation = RelationIsMapped(rel);
163-
164150
/*
165151
* Is it already toasted?
166152
*/
@@ -260,6 +246,12 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
260246
binary_upgrade_next_toast_pg_type_oid = InvalidOid;
261247
}
262248

249+
/* Toast table is shared if and only if its parent is. */
250+
shared_relation = rel->rd_rel->relisshared;
251+
252+
/* It's mapped if and only if its parent is, too */
253+
mapped_relation = RelationIsMapped(rel);
254+
263255
toast_relid = heap_create_with_catalog(toast_relname,
264256
namespaceid,
265257
rel->rd_rel->reltablespace,
@@ -398,7 +390,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
398390
* (1) there are any toastable attributes, and (2) the maximum length
399391
* of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to
400392
* create a toast table for something like "f1 varchar(20)".)
401-
* No need to create a TOAST table for partitioned tables.
402393
*/
403394
static bool
404395
needs_toast_table(Relation rel)
@@ -410,9 +401,28 @@ needs_toast_table(Relation rel)
410401
int32 tuple_length;
411402
int i;
412403

404+
/*
405+
* No need to create a TOAST table for partitioned tables.
406+
*/
413407
if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
414408
return false;
415409

410+
/*
411+
* We cannot allow toasting a shared relation after initdb (because
412+
* there's no way to mark it toasted in other databases' pg_class).
413+
*/
414+
if (rel->rd_rel->relisshared && !IsBootstrapProcessingMode())
415+
return false;
416+
417+
/*
418+
* Ignore attempts to create toast tables on catalog tables after initdb.
419+
* Which catalogs get toast tables is explicitly chosen in
420+
* catalog/toasting.h. (We could get here via some ALTER TABLE command if
421+
* the catalog doesn't have a toast table.)
422+
*/
423+
if (IsCatalogRelation(rel) && !IsBootstrapProcessingMode())
424+
return false;
425+
416426
tupdesc = rel->rd_att;
417427

418428
for (i = 0; i < tupdesc->natts; i++)

0 commit comments

Comments
 (0)