8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -332,6 +332,7 @@ TruncateRelation(const RangeVar *relation)
332
332
{
333
333
Relation rel ;
334
334
Oid relid ;
335
+ Oid toastrelid ;
335
336
ScanKeyData key ;
336
337
Relation fkeyRel ;
337
338
SysScanDesc fkeyScan ;
@@ -341,17 +342,20 @@ TruncateRelation(const RangeVar *relation)
341
342
rel = heap_openrv (relation , AccessExclusiveLock );
342
343
relid = RelationGetRelid (rel );
343
344
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" ,
354
357
RelationGetRelationName (rel ));
358
+ }
355
359
356
360
if (!allowSystemTableMods && IsSystemRelation (rel ))
357
361
elog (ERROR , "TRUNCATE cannot be used on system tables. '%s' is a system table" ,
@@ -375,25 +379,33 @@ TruncateRelation(const RangeVar *relation)
375
379
SnapshotNow , 1 , & key );
376
380
377
381
/*
378
- * First foriegn key found with us as the reference
382
+ * First foreign key found with us as the reference
379
383
* should throw an error.
380
384
*/
381
385
while (HeapTupleIsValid (tuple = systable_getnext (fkeyScan )))
382
386
{
383
387
Form_pg_constraint con = (Form_pg_constraint ) GETSTRUCT (tuple );
384
388
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 ),
387
392
NameStr (con -> conname ));
388
393
}
389
394
390
395
systable_endscan (fkeyScan );
391
396
heap_close (fkeyRel , AccessShareLock );
392
397
398
+ toastrelid = rel -> rd_rel -> reltoastrelid ;
399
+
393
400
/* Keep the lock until transaction commit */
394
401
heap_close (rel , NoLock );
395
402
403
+ /* Truncate the table proper */
396
404
heap_truncate (relid );
405
+
406
+ /* If it has a toast table, truncate that too */
407
+ if (OidIsValid (toastrelid ))
408
+ heap_truncate (toastrelid );
397
409
}
398
410
399
411
/*----------
0 commit comments