? src/test/regress/expected/truncate.out ? src/test/regress/sql/truncate.sql Index: src/backend/commands/tablecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v retrieving revision 1.12 diff -c -r1.12 tablecmds.c *** src/backend/commands/tablecmds.c 2002/04/27 21:24:34 1.12 --- src/backend/commands/tablecmds.c 2002/05/12 17:12:17 *************** *** 26,31 **** --- 26,32 ---- #include "catalog/pg_inherits.h" #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" + #include "catalog/pg_rewrite.h" #include "catalog/pg_trigger.h" #include "catalog/pg_type.h" #include "commands/tablecmds.h" *************** *** 302,307 **** --- 303,314 ---- { Relation rel; Oid relid; + ScanKeyData key; + Relation tgRel; + SysScanDesc tgScan; + Relation ruleRel; + SysScanDesc ruleScan; + HeapTuple tuple; /* Grab exclusive lock in preparation for truncate */ rel = heap_openrv(relation, AccessExclusiveLock); *************** *** 321,326 **** --- 328,381 ---- if (!pg_class_ownercheck(relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel)); + + /* + * Disallow truncate command if there are on delete triggers. + */ + tgRel = heap_openr(TriggerRelationName, RowExclusiveLock); + ScanKeyEntryInitialize(&key, 0, + Anum_pg_trigger_tgrelid, + F_OIDEQ, + ObjectIdGetDatum(relid)); + tgScan = systable_beginscan(tgRel, TriggerRelidNameIndex, true, + SnapshotNow, 1, &key); + while (HeapTupleIsValid(tuple = systable_getnext(tgScan))) + { + Form_pg_trigger trigger = (Form_pg_trigger) GETSTRUCT(tuple); + + if (TRIGGER_FOR_DELETE(trigger->tgtype)) + elog(ERROR, "TRUNCATE: Cannot truncate '%s' with ON DELETE Trigger", + RelationGetRelationName(rel), NameStr(trigger->tgname)); + } + systable_endscan(tgScan); + heap_close(tgRel, RowExclusiveLock); + + /* + * Disallow truncate command if there are on delete rules. + */ + ruleRel = heap_openr(RewriteRelationName, RowExclusiveLock); + + ScanKeyEntryInitialize(&key, + 0, + Anum_pg_rewrite_ev_class, + F_OIDEQ, + ObjectIdGetDatum(relid)); + + ruleScan = systable_beginscan(ruleRel, 0, false, + SnapshotNow, 1, &key); + + while (HeapTupleIsValid(tuple = systable_getnext(ruleScan))) + { + Form_pg_rewrite rewrite = (Form_pg_rewrite) GETSTRUCT(tuple); + + /* '4' is the character for CMD_DELETE */ + if (rewrite->ev_type == '4') + elog(ERROR, "TRUNCATE: Cannot truncate '%s' while ON DELETE Rule '%s' in place", + RelationGetRelationName(rel), NameStr(rewrite->rulename)); + } + + systable_endscan(ruleScan); + heap_close(ruleRel, RowExclusiveLock); /* Keep the lock until transaction commit */ heap_close(rel, NoLock); Index: src/test/regress/parallel_schedule =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/parallel_schedule,v retrieving revision 1.9 diff -c -r1.9 parallel_schedule *** src/test/regress/parallel_schedule 2002/04/05 11:56:55 1.9 --- src/test/regress/parallel_schedule 2002/05/12 17:12:24 *************** *** 74,77 **** # The sixth group of parallel test # ---------- # "plpgsql" cannot run concurrently with "rules" ! test: limit plpgsql temp domain --- 74,77 ---- # The sixth group of parallel test # ---------- # "plpgsql" cannot run concurrently with "rules" ! test: limit plpgsql temp domain truncate Index: src/test/regress/serial_schedule =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/serial_schedule,v retrieving revision 1.9 diff -c -r1.9 serial_schedule *** src/test/regress/serial_schedule 2002/04/05 11:56:55 1.9 --- src/test/regress/serial_schedule 2002/05/12 17:12:24 *************** *** 82,85 **** --- 82,86 ---- test: plpgsql test: temp test: domain + test: truncate