aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2019-03-19 10:48:03 +0100
committerPeter Eisentraut <peter@eisentraut.org>2019-03-19 11:15:50 +0100
commit590a87025b0aa9ebca53c7b71ddf036e5acd8f08 (patch)
tree0f435656ebdd8de843f8bfd2162778e70da90427 /src
parente537ac5182f8cfa7244a8c8ae772b787b2288605 (diff)
downloadpostgresql-590a87025b0aa9ebca53c7b71ddf036e5acd8f08.tar.gz
postgresql-590a87025b0aa9ebca53c7b71ddf036e5acd8f08.zip
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/e49f825b-fb25-0bc8-8afc-d5ad895c7975@2ndquadrant.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/toasting.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index f3306130cdf..2276d3c5d36 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -18,6 +18,7 @@
#include "access/tuptoaster.h"
#include "access/xact.h"
#include "catalog/binary_upgrade.h"
+#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/index.h"
@@ -147,21 +148,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
toastobject;
/*
- * Toast table is shared if and only if its parent is.
- *
- * We cannot allow toasting a shared relation after initdb (because
- * there's no way to mark it toasted in other databases' pg_class).
- */
- shared_relation = rel->rd_rel->relisshared;
- if (shared_relation && !IsBootstrapProcessingMode())
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("shared tables cannot be toasted after initdb")));
-
- /* It's mapped if and only if its parent is, too */
- mapped_relation = RelationIsMapped(rel);
-
- /*
* Is it already toasted?
*/
if (rel->rd_rel->reltoastrelid != InvalidOid)
@@ -260,6 +246,12 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
binary_upgrade_next_toast_pg_type_oid = InvalidOid;
}
+ /* Toast table is shared if and only if its parent is. */
+ shared_relation = rel->rd_rel->relisshared;
+
+ /* It's mapped if and only if its parent is, too */
+ mapped_relation = RelationIsMapped(rel);
+
toast_relid = heap_create_with_catalog(toast_relname,
namespaceid,
rel->rd_rel->reltablespace,
@@ -398,7 +390,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
* (1) there are any toastable attributes, and (2) the maximum length
* of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to
* create a toast table for something like "f1 varchar(20)".)
- * No need to create a TOAST table for partitioned tables.
*/
static bool
needs_toast_table(Relation rel)
@@ -410,9 +401,28 @@ needs_toast_table(Relation rel)
int32 tuple_length;
int i;
+ /*
+ * No need to create a TOAST table for partitioned tables.
+ */
if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
return false;
+ /*
+ * We cannot allow toasting a shared relation after initdb (because
+ * there's no way to mark it toasted in other databases' pg_class).
+ */
+ if (rel->rd_rel->relisshared && !IsBootstrapProcessingMode())
+ return false;
+
+ /*
+ * Ignore attempts to create toast tables on catalog tables after initdb.
+ * Which catalogs get toast tables is explicitly chosen in
+ * catalog/toasting.h. (We could get here via some ALTER TABLE command if
+ * the catalog doesn't have a toast table.)
+ */
+ if (IsCatalogRelation(rel) && !IsBootstrapProcessingMode())
+ return false;
+
tupdesc = rel->rd_att;
for (i = 0; i < tupdesc->natts; i++)