*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.190 2004/09/16 20:17:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.191 2004/10/04 21:52:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static void AbortTransaction(void);
static void AtAbort_Memory(void);
static void AtCleanup_Memory(void);
+static void AtAbort_ResourceOwner(void);
static void AtCommit_LocalCache(void);
static void AtCommit_Memory(void);
static void AtStart_Cache(void);
static void AtSubAbort_Memory(void);
static void AtSubCleanup_Memory(void);
+static void AtSubAbort_ResourceOwner(void);
static void AtSubCommit_Memory(void);
static void AtSubStart_Memory(void);
static void AtSubStart_ResourceOwner(void);
MemoryContextSwitchTo(TopMemoryContext);
}
-
/*
* AtSubAbort_Memory
*/
MemoryContextSwitchTo(TopTransactionContext);
}
+
+/*
+ * AtAbort_ResourceOwner
+ */
+static void
+AtAbort_ResourceOwner(void)
+{
+ /*
+ * Make sure we have a valid ResourceOwner, if possible (else it
+ * will be NULL, which is OK)
+ */
+ CurrentResourceOwner = TopTransactionResourceOwner;
+}
+
+/*
+ * AtSubAbort_ResourceOwner
+ */
+static void
+AtSubAbort_ResourceOwner(void)
+{
+ TransactionState s = CurrentTransactionState;
+
+ /* Make sure we have a valid ResourceOwner */
+ CurrentResourceOwner = s->curTransactionOwner;
+}
+
+
/*
* AtSubAbort_childXids
*/
*/
s->state = TRANS_ABORT;
- /* Make sure we are in a valid memory context */
+ /* Make sure we have a valid memory context and resource owner */
AtAbort_Memory();
+ AtAbort_ResourceOwner();
/*
* Reset user id which might have been changed transiently. We cannot
* do abort processing
*/
AtSubAbort_Memory();
+ AtSubAbort_ResourceOwner();
/*
* We can skip all this stuff if the subxact failed before creating
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.87 2004/09/13 20:07:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.88 2004/10/04 21:52:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
char *completionTag)
{
bool result;
+ ResourceOwner saveTopTransactionResourceOwner;
+ MemoryContext saveTopTransactionContext;
Portal saveActivePortal;
Snapshot saveActiveSnapshot;
ResourceOwner saveResourceOwner;
MemoryContext savePortalContext;
MemoryContext saveQueryContext;
- MemoryContext oldContext;
+ MemoryContext saveMemoryContext;
AssertArg(PortalIsValid(portal));
/*
* Set up global portal context pointers.
+ *
+ * We have to play a special game here to support utility commands like
+ * VACUUM and CLUSTER, which internally start and commit transactions.
+ * When we are called to execute such a command, CurrentResourceOwner
+ * will be pointing to the TopTransactionResourceOwner --- which will
+ * be destroyed and replaced in the course of the internal commit and
+ * restart. So we need to be prepared to restore it as pointing to
+ * the exit-time TopTransactionResourceOwner. (Ain't that ugly? This
+ * idea of internally starting whole new transactions is not good.)
+ * CurrentMemoryContext has a similar problem, but the other pointers
+ * we save here will be NULL or pointing to longer-lived objects.
*/
+ saveTopTransactionResourceOwner = TopTransactionResourceOwner;
+ saveTopTransactionContext = TopTransactionContext;
saveActivePortal = ActivePortal;
saveActiveSnapshot = ActiveSnapshot;
saveResourceOwner = CurrentResourceOwner;
savePortalContext = PortalContext;
saveQueryContext = QueryContext;
+ saveMemoryContext = CurrentMemoryContext;
PG_TRY();
{
ActivePortal = portal;
PortalContext = PortalGetHeapMemory(portal);
QueryContext = portal->queryContext;
- oldContext = MemoryContextSwitchTo(PortalContext);
+ MemoryContextSwitchTo(PortalContext);
switch (portal->strategy)
{
portal->status = PORTAL_FAILED;
/* Restore global vars and propagate error */
+ if (saveMemoryContext == saveTopTransactionContext)
+ MemoryContextSwitchTo(TopTransactionContext);
+ else
+ MemoryContextSwitchTo(saveMemoryContext);
ActivePortal = saveActivePortal;
ActiveSnapshot = saveActiveSnapshot;
- CurrentResourceOwner = saveResourceOwner;
+ if (saveResourceOwner == saveTopTransactionResourceOwner)
+ CurrentResourceOwner = TopTransactionResourceOwner;
+ else
+ CurrentResourceOwner = saveResourceOwner;
PortalContext = savePortalContext;
QueryContext = saveQueryContext;
}
PG_END_TRY();
- MemoryContextSwitchTo(oldContext);
-
+ if (saveMemoryContext == saveTopTransactionContext)
+ MemoryContextSwitchTo(TopTransactionContext);
+ else
+ MemoryContextSwitchTo(saveMemoryContext);
ActivePortal = saveActivePortal;
ActiveSnapshot = saveActiveSnapshot;
- CurrentResourceOwner = saveResourceOwner;
+ if (saveResourceOwner == saveTopTransactionResourceOwner)
+ CurrentResourceOwner = TopTransactionResourceOwner;
+ else
+ CurrentResourceOwner = saveResourceOwner;
PortalContext = savePortalContext;
QueryContext = saveQueryContext;