diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-10-21 22:06:20 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-10-21 22:06:20 +0000 |
commit | 200b15161556a2bc6e6b0cccd08be1ca3a438643 (patch) | |
tree | c520e1a6420f079c6b87594bd9687031f8e8ecc4 /src/backend/commands | |
parent | f724c164d3b9194555a7a7ee10bbb4bfb63caa7a (diff) | |
download | postgresql-200b15161556a2bc6e6b0cccd08be1ca3a438643.tar.gz postgresql-200b15161556a2bc6e6b0cccd08be1ca3a438643.zip |
Fix places that were using IsTransactionBlock() as an (inadequate) check
that they'd get to commit immediately on finishing. There's now a
centralized routine PreventTransactionChain() that implements the
necessary tests.
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/dbcommands.c | 8 | ||||
-rw-r--r-- | src/backend/commands/indexcmds.c | 49 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 12 | ||||
-rw-r--r-- | src/backend/commands/vacuum.c | 10 |
4 files changed, 41 insertions, 38 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index addb6dcae4e..327aac29593 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.105 2002/09/04 20:31:15 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.106 2002/10/21 22:06:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -152,8 +152,7 @@ createdb(const CreatedbStmt *stmt) } /* don't call this in a transaction block */ - if (IsTransactionBlock()) - elog(ERROR, "CREATE DATABASE: may not be called in a transaction block"); + PreventTransactionChain((void *) stmt, "CREATE DATABASE"); /* * Check for db name conflict. There is a race condition here, since @@ -382,8 +381,7 @@ dropdb(const char *dbname) if (strcmp(dbname, DatabaseName) == 0) elog(ERROR, "DROP DATABASE: cannot be executed on the currently open database"); - if (IsTransactionBlock()) - elog(ERROR, "DROP DATABASE: may not be called in a transaction block"); + PreventTransactionChain((void *) dbname, "DROP DATABASE"); /* * Obtain exclusive lock on pg_database. We need this to ensure that diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 43aec83ce32..5447780b69e 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.91 2002/10/19 20:15:08 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.92 2002/10/21 22:06:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -560,15 +560,10 @@ ReindexIndex(RangeVar *indexRelation, bool force /* currently unused */ ) { Oid indOid; HeapTuple tuple; - bool overwrite = false; + bool overwrite; - /* - * REINDEX within a transaction block is dangerous, because if the - * transaction is later rolled back we have no way to undo truncation - * of the index's physical file. Disallow it. - */ - if (IsTransactionBlock()) - elog(ERROR, "REINDEX cannot run inside a BEGIN/END block"); + /* Choose in-place-or-not mode */ + overwrite = IsIgnoringSystemIndexes(); indOid = RangeVarGetRelid(indexRelation, false); tuple = SearchSysCache(RELOID, @@ -595,8 +590,14 @@ ReindexIndex(RangeVar *indexRelation, bool force /* currently unused */ ) ReleaseSysCache(tuple); - if (IsIgnoringSystemIndexes()) - overwrite = true; + /* + * In-place REINDEX within a transaction block is dangerous, because + * if the transaction is later rolled back we have no way to undo + * truncation of the index's physical file. Disallow it. + */ + if (overwrite) + PreventTransactionChain((void *) indexRelation, "REINDEX"); + if (!reindex_index(indOid, force, overwrite)) elog(WARNING, "index \"%s\" wasn't reindexed", indexRelation->relname); } @@ -611,14 +612,6 @@ ReindexTable(RangeVar *relation, bool force) Oid heapOid; char relkind; - /* - * REINDEX within a transaction block is dangerous, because if the - * transaction is later rolled back we have no way to undo truncation - * of the index's physical file. Disallow it. - */ - if (IsTransactionBlock()) - elog(ERROR, "REINDEX cannot run inside a BEGIN/END block"); - heapOid = RangeVarGetRelid(relation, false); relkind = get_rel_relkind(heapOid); @@ -626,6 +619,17 @@ ReindexTable(RangeVar *relation, bool force) elog(ERROR, "relation \"%s\" is of type \"%c\"", relation->relname, relkind); + /* + * In-place REINDEX within a transaction block is dangerous, because + * if the transaction is later rolled back we have no way to undo + * truncation of the index's physical file. Disallow it. + * + * XXX we assume that in-place reindex will only be done if + * IsIgnoringSystemIndexes() is true. + */ + if (IsIgnoringSystemIndexes()) + PreventTransactionChain((void *) relation, "REINDEX"); + if (!reindex_relation(heapOid, force)) elog(WARNING, "table \"%s\" wasn't reindexed", relation->relname); } @@ -666,12 +670,7 @@ ReindexDatabase(const char *dbname, bool force, bool all) * transaction, then our commit- and start-transaction-command calls * would not have the intended effect! */ - if (IsTransactionBlock()) - elog(ERROR, "REINDEX DATABASE cannot run inside a BEGIN/END block"); - - /* Running this from a function would free the function context */ - if (!MemoryContextContains(QueryContext, (void *) dbname)) - elog(ERROR, "REINDEX DATABASE cannot be executed from a function"); + PreventTransactionChain((void *) dbname, "REINDEX"); /* * Create a memory context that will survive forced transaction diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index ae15b815332..f211448f413 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.49 2002/10/21 20:31:51 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.50 2002/10/21 22:06:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -376,6 +376,16 @@ TruncateRelation(const RangeVar *relation) aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel)); /* + * Truncate within a transaction block is dangerous, because if + * the transaction is later rolled back we have no way to undo + * truncation of the relation's physical file. Disallow it except for + * a rel created in the current xact (which would be deleted on abort, + * anyway). + */ + if (!rel->rd_isnew) + PreventTransactionChain((void *) relation, "TRUNCATE TABLE"); + + /* * Don't allow truncate on temp tables of other backends ... their * local buffer manager is not going to cope. */ diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 2ff3aae6f8a..160289c91e0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.242 2002/10/19 20:15:09 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.243 2002/10/21 22:06:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -177,12 +177,8 @@ vacuum(VacuumStmt *vacstmt) * user's transaction too, which would certainly not be the desired * behavior. */ - if (vacstmt->vacuum && IsTransactionBlock()) - elog(ERROR, "%s cannot run inside a BEGIN/END block", stmttype); - - /* Running VACUUM from a function would free the function context */ - if (vacstmt->vacuum && !MemoryContextContains(QueryContext, vacstmt)) - elog(ERROR, "%s cannot be executed from a function", stmttype); + if (vacstmt->vacuum) + PreventTransactionChain((void *) vacstmt, stmttype); /* * Send info about dead objects to the statistics collector |