1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-23 14:01:44 +03:00

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.
This commit is contained in:
Tom Lane
2002-10-21 22:06:20 +00:00
parent f724c164d3
commit 200b151615
9 changed files with 107 additions and 87 deletions

View File

@ -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