aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 4b3202c8c43..a555371d939 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -40,6 +40,7 @@
#include "catalog/pg_depend.h"
#include "catalog/pg_foreign_table.h"
#include "catalog/pg_inherits.h"
+#include "catalog/pg_largeobject.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_statistic_ext.h"
@@ -2181,7 +2182,15 @@ truncate_check_rel(Oid relid, Form_pg_class reltuple)
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not a table", relname)));
- if (!allowSystemTableMods && IsSystemClass(relid, reltuple))
+ /*
+ * Most system catalogs can't be truncated at all, or at least not unless
+ * allow_system_table_mods=on. As an exception, however, we allow
+ * pg_largeobject to be truncated as part of pg_upgrade, because we need
+ * to change its relfilenode to match the old cluster, and allowing a
+ * TRUNCATE command to be executed is the easiest way of doing that.
+ */
+ if (!allowSystemTableMods && IsSystemClass(relid, reltuple)
+ && (!IsBinaryUpgrade || relid != LargeObjectRelationId))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied: \"%s\" is a system catalog",