Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0f11129

Browse files
committed
Code review for recent TRUNCATE changes. Tighten relation-kind check,
tighten foreign-key check (a self-reference should not prevent TRUNCATE), improve error message, cause a relation's TOAST table to be truncated along with the relation.
1 parent b4f24fe commit 0f11129

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

src/backend/commands/tablecmds.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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
/*----------

src/test/regress/expected/truncate.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ SELECT * FROM truncate_a;
2727
(1 row)
2828

2929
TRUNCATE truncate_a;
30-
ERROR: TRUNCATE cannot be used as other tables reference this one via foreign key constraint $1
30+
ERROR: TRUNCATE cannot be used as table truncate_b references this one via foreign key constraint $1
3131
SELECT * FROM truncate_a;
3232
col1
3333
------

0 commit comments

Comments
 (0)