aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2002-08-22 04:51:06 +0000
committerBruce Momjian <bruce@momjian.us>2002-08-22 04:51:06 +0000
commit47b37a6bfaa073076c8607cdd4f65ddd569aaefa (patch)
tree289bf3468cc05ff203e5bad9abd14fa26113a9a1 /src/backend/commands/tablecmds.c
parentdac22ee43c841768900afbe5b7e697f0c515d2e0 (diff)
downloadpostgresql-47b37a6bfaa073076c8607cdd4f65ddd569aaefa.tar.gz
postgresql-47b37a6bfaa073076c8607cdd4f65ddd569aaefa.zip
# Disallow TRUNCATE on tables that are involved in referential
constraints The issue with finding and removing foreign key constraints is no longer an issue, so please apply the attached. It does NOT check for rules or on delete triggers (old style foreign keys) as those are difficult to deal with (remove, truncate, re-add). Rod Taylor
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c6e8d686d41..1961ca1344a 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.30 2002/08/19 15:08:46 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.31 2002/08/22 04:51:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -332,6 +332,10 @@ TruncateRelation(const RangeVar *relation)
{
Relation rel;
Oid relid;
+ ScanKeyData key;
+ Relation fkeyRel;
+ SysScanDesc fkeyScan;
+ HeapTuple tuple;
/* Grab exclusive lock in preparation for truncate */
rel = heap_openrv(relation, AccessExclusiveLock);
@@ -356,6 +360,36 @@ TruncateRelation(const RangeVar *relation)
if (!pg_class_ownercheck(relid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
+ /*
+ * Don't allow truncate on tables which are referenced
+ * by foreign keys
+ */
+ fkeyRel = heap_openr(ConstraintRelationName, AccessShareLock);
+
+ ScanKeyEntryInitialize(&key, 0,
+ Anum_pg_constraint_confrelid,
+ F_OIDEQ,
+ ObjectIdGetDatum(relid));
+
+ fkeyScan = systable_beginscan(fkeyRel, 0, false,
+ SnapshotNow, 1, &key);
+
+ /*
+ * First foriegn key found with us as the reference
+ * should throw an error.
+ */
+ while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan)))
+ {
+ Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple);
+
+ if (con->contype == 'f')
+ elog(ERROR, "TRUNCATE cannot be used as other tables reference this one via foreign key constraint %s",
+ NameStr(con->conname));
+ }
+
+ systable_endscan(fkeyScan);
+ heap_close(fkeyRel, AccessShareLock);
+
/* Keep the lock until transaction commit */
heap_close(rel, NoLock);