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

Commit 0041202

Browse files
committed
Disallow DROP TABLE/DROP INDEX inside a transaction block.
We can't support these properly, since once the relation's physical files are unlinked, there's no way to roll back the transaction. I suppose we could postpone the unlink till transaction commit, but then what of BEGIN; DROP TABLE foo; CREATE TABLE foo; ? The code does allow dropping a table/index created in the current transaction block, however, since the post-abort state would be that the table doesn't exist anyway.
1 parent 6645a73 commit 0041202

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

src/backend/catalog/heap.c

+19-10
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.94 1999/09/04 22:00:29 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.95 1999/09/05 17:43:47 tgl Exp $
1111
*
1212
*
1313
* INTERFACE ROUTINES
@@ -30,6 +30,7 @@
3030
#include "miscadmin.h"
3131

3232
#include "access/heapam.h"
33+
#include "access/xact.h"
3334
#include "catalog/catalog.h"
3435
#include "catalog/catname.h"
3536
#include "catalog/heap.h"
@@ -1232,7 +1233,7 @@ heap_destroy_with_catalog(char *relname)
12321233
bool istemp = (get_temp_rel_by_name(relname) != NULL);
12331234

12341235
/* ----------------
1235-
* first open the relation. if the relation does exist,
1236+
* first open the relation. if the relation doesn't exist,
12361237
* heap_openr() returns NULL.
12371238
* ----------------
12381239
*/
@@ -1253,6 +1254,17 @@ heap_destroy_with_catalog(char *relname)
12531254
elog(ERROR, "System relation '%s' cannot be destroyed",
12541255
&rel->rd_rel->relname);
12551256

1257+
/* ----------------
1258+
* We do not allow DROP TABLE within a transaction block, because
1259+
* if the transaction is later rolled back there would be no way to
1260+
* undo the unlink of the relation's physical file. The sole exception
1261+
* is for relations created in the current transaction, since the post-
1262+
* abort state would be that they don't exist anyway.
1263+
* ----------------
1264+
*/
1265+
if (IsTransactionBlock() && ! rel->rd_myxactonly)
1266+
elog(ERROR, "Cannot destroy relation within a transaction block");
1267+
12561268
/* ----------------
12571269
* remove inheritance information
12581270
* ----------------
@@ -1307,17 +1319,10 @@ heap_destroy_with_catalog(char *relname)
13071319
*/
13081320
ReleaseRelationBuffers(rel);
13091321

1310-
/* ----------------
1311-
* flush the relation from the relcache
1312-
* ----------------
1313-
* Does nothing!!! Flushing moved below. - vadim 06/04/97
1314-
RelationIdInvalidateRelationCacheByRelationId(rel->rd_id);
1315-
*/
1316-
13171322
RemoveConstraints(rel);
13181323

13191324
/* ----------------
1320-
* unlink the relation and finish up.
1325+
* unlink the relation's physical file and finish up.
13211326
* ----------------
13221327
*/
13231328
if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked))
@@ -1329,6 +1334,10 @@ heap_destroy_with_catalog(char *relname)
13291334

13301335
heap_close(rel);
13311336

1337+
/* ----------------
1338+
* flush the relation from the relcache
1339+
* ----------------
1340+
*/
13321341
RelationForgetRelation(rid);
13331342
}
13341343

src/backend/catalog/index.c

+14-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.88 1999/09/04 22:00:29 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.89 1999/09/05 17:43:47 tgl Exp $
1111
*
1212
*
1313
* INTERFACE ROUTINES
@@ -23,6 +23,7 @@
2323
#include "access/genam.h"
2424
#include "access/heapam.h"
2525
#include "access/istrat.h"
26+
#include "access/xact.h"
2627
#include "bootstrap/bootstrap.h"
2728
#include "catalog/catname.h"
2829
#include "catalog/heap.h"
@@ -1105,6 +1106,17 @@ index_destroy(Oid indexId)
11051106
/* Open now to obtain lock by referencing table? bjm */
11061107
userindexRelation = index_open(indexId);
11071108

1109+
/* ----------------
1110+
* We do not allow DROP INDEX within a transaction block, because
1111+
* if the transaction is later rolled back there would be no way to
1112+
* undo the unlink of the relation's physical file. The sole exception
1113+
* is for relations created in the current transaction, since the post-
1114+
* abort state would be that they don't exist anyway.
1115+
* ----------------
1116+
*/
1117+
if (IsTransactionBlock() && ! userindexRelation->rd_myxactonly)
1118+
elog(ERROR, "Cannot destroy index within a transaction block");
1119+
11081120
/* ----------------
11091121
* fix RELATION relation
11101122
* ----------------
@@ -1164,7 +1176,7 @@ index_destroy(Oid indexId)
11641176
ReleaseRelationBuffers(userindexRelation);
11651177

11661178
if (smgrunlink(DEFAULT_SMGR, userindexRelation) != SM_SUCCESS)
1167-
elog(ERROR, "amdestroyr: unlink: %m");
1179+
elog(ERROR, "index_destroy: unlink: %m");
11681180

11691181
index_close(userindexRelation);
11701182
RelationForgetRelation(RelationGetRelid(userindexRelation));

0 commit comments

Comments
 (0)