Hi, The current behavior of session_replication_role = replica with TRUNCATE is not the same of with the other commands. It does not check FKs for INSERT/UPDATE/DELETE but it does for TRUNCATE, so one cannot execute TRUNCATE on a table when it is possible to DELETE from table without WHERE clause.
I'm attaching a simple patch to make TRUNCATE match behavior of DELETE for session_replication_role = replica. Regards, Marco -- Marco Nenciarini - 2ndQuadrant Italy PostgreSQL Training, Services and Support [email protected] | www.2ndQuadrant.it
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d979ce266d..296807849f 100644
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 1341,1356 **** ExecuteTruncate(TruncateStmt *stmt)
}
/*
! * Check foreign key references. In CASCADE mode, this should be
! * unnecessary since we just pulled in all the references; but as a
! * cross-check, do it anyway if in an Assert-enabled build.
*/
#ifdef USE_ASSERT_CHECKING
- heap_truncate_check_FKs(rels, false);
- #else
- if (stmt->behavior == DROP_RESTRICT)
heap_truncate_check_FKs(rels, false);
#endif
/*
* If we are asked to restart sequences, find all the sequences, lock
them
--- 1341,1364 ----
}
/*
! * Suppress foreign key references check if session replication role is
! * set to REPLICA.
*/
+ if (SessionReplicationRole != SESSION_REPLICATION_ROLE_REPLICA)
+ {
+
+ /*
+ * Check foreign key references. In CASCADE mode, this should
be
+ * unnecessary since we just pulled in all the references; but
as a
+ * cross-check, do it anyway if in an Assert-enabled build.
+ */
#ifdef USE_ASSERT_CHECKING
heap_truncate_check_FKs(rels, false);
+ #else
+ if (stmt->behavior == DROP_RESTRICT)
+ heap_truncate_check_FKs(rels, false);
#endif
+ }
/*
* If we are asked to restart sequences, find all the sequences, lock
them
signature.asc
Description: OpenPGP digital signature
