88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.31 2002/08/22 04:51:05 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.32 2002/08/22 14:23:36 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -332,6 +332,7 @@ TruncateRelation(const RangeVar *relation)
332332{
333333 Relation rel ;
334334 Oid relid ;
335+ Oid toastrelid ;
335336 ScanKeyData key ;
336337 Relation fkeyRel ;
337338 SysScanDesc fkeyScan ;
@@ -341,17 +342,20 @@ TruncateRelation(const RangeVar *relation)
341342 rel = heap_openrv (relation , AccessExclusiveLock );
342343 relid = RelationGetRelid (rel );
343344
344- if (rel -> rd_rel -> relkind == RELKIND_SEQUENCE )
345- elog (ERROR , "TRUNCATE cannot be used on sequences. '%s' is a sequence" ,
346- RelationGetRelationName (rel ));
347-
348- if (rel -> rd_rel -> relkind == RELKIND_VIEW )
349- elog (ERROR , "TRUNCATE cannot be used on views. '%s' is a view" ,
350- RelationGetRelationName (rel ));
351-
352- if (rel -> rd_rel -> relkind == RELKIND_COMPOSITE_TYPE )
353- elog (ERROR , "TRUNCATE cannot be used on type relations. '%s' is a type" ,
345+ /* Only allow truncate on regular tables */
346+ if (rel -> rd_rel -> relkind != RELKIND_RELATION )
347+ {
348+ /* special errors for backwards compatibility */
349+ if (rel -> rd_rel -> relkind == RELKIND_SEQUENCE )
350+ elog (ERROR , "TRUNCATE cannot be used on sequences. '%s' is a sequence" ,
351+ RelationGetRelationName (rel ));
352+ if (rel -> rd_rel -> relkind == RELKIND_VIEW )
353+ elog (ERROR , "TRUNCATE cannot be used on views. '%s' is a view" ,
354+ RelationGetRelationName (rel ));
355+ /* else a generic error message will do */
356+ elog (ERROR , "TRUNCATE can only be used on tables. '%s' is not a table" ,
354357 RelationGetRelationName (rel ));
358+ }
355359
356360 if (!allowSystemTableMods && IsSystemRelation (rel ))
357361 elog (ERROR , "TRUNCATE cannot be used on system tables. '%s' is a system table" ,
@@ -375,25 +379,33 @@ TruncateRelation(const RangeVar *relation)
375379 SnapshotNow , 1 , & key );
376380
377381 /*
378- * First foriegn key found with us as the reference
382+ * First foreign key found with us as the reference
379383 * should throw an error.
380384 */
381385 while (HeapTupleIsValid (tuple = systable_getnext (fkeyScan )))
382386 {
383387 Form_pg_constraint con = (Form_pg_constraint ) GETSTRUCT (tuple );
384388
385- if (con -> contype == 'f' )
386- elog (ERROR , "TRUNCATE cannot be used as other tables reference this one via foreign key constraint %s" ,
389+ if (con -> contype == 'f' && con -> conrelid != relid )
390+ elog (ERROR , "TRUNCATE cannot be used as table %s references this one via foreign key constraint %s" ,
391+ get_rel_name (con -> conrelid ),
387392 NameStr (con -> conname ));
388393 }
389394
390395 systable_endscan (fkeyScan );
391396 heap_close (fkeyRel , AccessShareLock );
392397
398+ toastrelid = rel -> rd_rel -> reltoastrelid ;
399+
393400 /* Keep the lock until transaction commit */
394401 heap_close (rel , NoLock );
395402
403+ /* Truncate the table proper */
396404 heap_truncate (relid );
405+
406+ /* If it has a toast table, truncate that too */
407+ if (OidIsValid (toastrelid ))
408+ heap_truncate (toastrelid );
397409}
398410
399411/*----------
0 commit comments