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

Lines changed: 19 additions & 10 deletions
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

Lines changed: 14 additions & 2 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy