summaryrefslogtreecommitdiff
path: root/src/backend/commands/trigger.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-01-24 21:49:48 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-01-24 21:49:48 +0000
commita82c3f463490fe3edfee50ff713956e82f87b2d7 (patch)
tree56e0d934ad7b7647b0a780abe62540a53fe8e853 /src/backend/commands/trigger.c
parent84cce313720b75642a098ceacdb2dc23fc35fcc5 (diff)
Fix assorted core dumps and Assert failures that could occur during
AbortTransaction or AbortSubTransaction, when trying to clean up after an error that prevented (sub)transaction start from completing: * access to TopTransactionResourceOwner that might not exist * assert failure in AtEOXact_GUC, if AtStart_GUC not called yet * assert failure or core dump in AfterTriggerEndSubXact, if AfterTriggerBeginSubXact not called yet Per testing by injecting elog(ERROR) at successive steps in StartTransaction and StartSubTransaction. It's not clear whether all of these cases could really occur in the field, but at least one of them is easily exposed by simple stress testing, as per my accidental discovery yesterday.
Diffstat (limited to 'src/backend/commands/trigger.c')
-rw-r--r--src/backend/commands/trigger.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 5cf4f412075..6b360afd19e 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.210.2.8 2009/10/27 20:14:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.210.2.9 2010/01/24 21:49:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2773,10 +2773,9 @@ AfterTriggerEndSubXact(bool isCommit)
/*
* Pop the prior state if needed.
*/
- Assert(my_level < afterTriggers->maxtransdepth);
-
if (isCommit)
{
+ Assert(my_level < afterTriggers->maxtransdepth);
/* If we saved a prior state, we don't need it anymore */
state = afterTriggers->state_stack[my_level];
if (state != NULL)
@@ -2807,7 +2806,15 @@ AfterTriggerEndSubXact(bool isCommit)
else
{
/*
- * Aborting. We don't really need to release the subxact's event_cxt,
+ * Aborting. It is possible subxact start failed before calling
+ * AfterTriggerBeginSubXact, in which case we mustn't risk touching
+ * stack levels that aren't there.
+ */
+ if (my_level >= afterTriggers->maxtransdepth)
+ return;
+
+ /*
+ * We don't really need to release the subxact's event_cxt,
* since it will go away anyway when CurTransactionContext gets reset,
* but doing so early in subxact abort helps free space we might need.
*