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.
This commit is contained in:
parent
6645a73863
commit
0041202b98
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.94 1999/09/04 22:00:29 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.95 1999/09/05 17:43:47 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -30,6 +30,7 @@
|
|||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
|
#include "access/xact.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/heap.h"
|
#include "catalog/heap.h"
|
||||||
@ -1232,7 +1233,7 @@ heap_destroy_with_catalog(char *relname)
|
|||||||
bool istemp = (get_temp_rel_by_name(relname) != NULL);
|
bool istemp = (get_temp_rel_by_name(relname) != NULL);
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* first open the relation. if the relation does exist,
|
* first open the relation. if the relation doesn't exist,
|
||||||
* heap_openr() returns NULL.
|
* heap_openr() returns NULL.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
@ -1253,6 +1254,17 @@ heap_destroy_with_catalog(char *relname)
|
|||||||
elog(ERROR, "System relation '%s' cannot be destroyed",
|
elog(ERROR, "System relation '%s' cannot be destroyed",
|
||||||
&rel->rd_rel->relname);
|
&rel->rd_rel->relname);
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* We do not allow DROP TABLE within a transaction block, because
|
||||||
|
* if the transaction is later rolled back there would be no way to
|
||||||
|
* undo the unlink of the relation's physical file. The sole exception
|
||||||
|
* is for relations created in the current transaction, since the post-
|
||||||
|
* abort state would be that they don't exist anyway.
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
if (IsTransactionBlock() && ! rel->rd_myxactonly)
|
||||||
|
elog(ERROR, "Cannot destroy relation within a transaction block");
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* remove inheritance information
|
* remove inheritance information
|
||||||
* ----------------
|
* ----------------
|
||||||
@ -1307,17 +1319,10 @@ heap_destroy_with_catalog(char *relname)
|
|||||||
*/
|
*/
|
||||||
ReleaseRelationBuffers(rel);
|
ReleaseRelationBuffers(rel);
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* flush the relation from the relcache
|
|
||||||
* ----------------
|
|
||||||
* Does nothing!!! Flushing moved below. - vadim 06/04/97
|
|
||||||
RelationIdInvalidateRelationCacheByRelationId(rel->rd_id);
|
|
||||||
*/
|
|
||||||
|
|
||||||
RemoveConstraints(rel);
|
RemoveConstraints(rel);
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* unlink the relation and finish up.
|
* unlink the relation's physical file and finish up.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked))
|
if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked))
|
||||||
@ -1329,6 +1334,10 @@ heap_destroy_with_catalog(char *relname)
|
|||||||
|
|
||||||
heap_close(rel);
|
heap_close(rel);
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* flush the relation from the relcache
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
RelationForgetRelation(rid);
|
RelationForgetRelation(rid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.88 1999/09/04 22:00:29 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.89 1999/09/05 17:43:47 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -23,6 +23,7 @@
|
|||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "access/istrat.h"
|
#include "access/istrat.h"
|
||||||
|
#include "access/xact.h"
|
||||||
#include "bootstrap/bootstrap.h"
|
#include "bootstrap/bootstrap.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/heap.h"
|
#include "catalog/heap.h"
|
||||||
@ -1105,6 +1106,17 @@ index_destroy(Oid indexId)
|
|||||||
/* Open now to obtain lock by referencing table? bjm */
|
/* Open now to obtain lock by referencing table? bjm */
|
||||||
userindexRelation = index_open(indexId);
|
userindexRelation = index_open(indexId);
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* We do not allow DROP INDEX within a transaction block, because
|
||||||
|
* if the transaction is later rolled back there would be no way to
|
||||||
|
* undo the unlink of the relation's physical file. The sole exception
|
||||||
|
* is for relations created in the current transaction, since the post-
|
||||||
|
* abort state would be that they don't exist anyway.
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
if (IsTransactionBlock() && ! userindexRelation->rd_myxactonly)
|
||||||
|
elog(ERROR, "Cannot destroy index within a transaction block");
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* fix RELATION relation
|
* fix RELATION relation
|
||||||
* ----------------
|
* ----------------
|
||||||
@ -1164,7 +1176,7 @@ index_destroy(Oid indexId)
|
|||||||
ReleaseRelationBuffers(userindexRelation);
|
ReleaseRelationBuffers(userindexRelation);
|
||||||
|
|
||||||
if (smgrunlink(DEFAULT_SMGR, userindexRelation) != SM_SUCCESS)
|
if (smgrunlink(DEFAULT_SMGR, userindexRelation) != SM_SUCCESS)
|
||||||
elog(ERROR, "amdestroyr: unlink: %m");
|
elog(ERROR, "index_destroy: unlink: %m");
|
||||||
|
|
||||||
index_close(userindexRelation);
|
index_close(userindexRelation);
|
||||||
RelationForgetRelation(RelationGetRelid(userindexRelation));
|
RelationForgetRelation(RelationGetRelid(userindexRelation));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user