summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xact.c10
-rw-r--r--src/include/access/xact.h7
-rw-r--r--src/pl/plpgsql/src/pl_exec.c26
3 files changed, 27 insertions, 16 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 81d2687495..9a9724574b 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -1825,6 +1825,8 @@ CommitTransaction(void)
break;
}
+ CallXactCallbacks(XACT_EVENT_PRE_COMMIT);
+
/*
* The remaining actions cannot call any user-defined code, so it's safe
* to start shutting down within-transaction services. But note that most
@@ -2028,6 +2030,8 @@ PrepareTransaction(void)
break;
}
+ CallXactCallbacks(XACT_EVENT_PRE_PREPARE);
+
/*
* The remaining actions cannot call any user-defined code, so it's safe
* to start shutting down within-transaction services. But note that most
@@ -4058,8 +4062,12 @@ CommitSubTransaction(void)
elog(WARNING, "CommitSubTransaction while in %s state",
TransStateAsString(s->state));
- /* Pre-commit processing goes here -- nothing to do at the moment */
+ /* Pre-commit processing goes here */
+
+ CallSubXactCallbacks(SUBXACT_EVENT_PRE_COMMIT_SUB, s->subTransactionId,
+ s->parent->subTransactionId);
+ /* Do the actual "commit", such as it is */
s->state = TRANS_COMMIT;
/* Must CCI to ensure commands of subtransaction are seen as done */
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index fcdff93272..8cadc54971 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -76,7 +76,9 @@ typedef enum
{
XACT_EVENT_COMMIT,
XACT_EVENT_ABORT,
- XACT_EVENT_PREPARE
+ XACT_EVENT_PREPARE,
+ XACT_EVENT_PRE_COMMIT,
+ XACT_EVENT_PRE_PREPARE
} XactEvent;
typedef void (*XactCallback) (XactEvent event, void *arg);
@@ -85,7 +87,8 @@ typedef enum
{
SUBXACT_EVENT_START_SUB,
SUBXACT_EVENT_COMMIT_SUB,
- SUBXACT_EVENT_ABORT_SUB
+ SUBXACT_EVENT_ABORT_SUB,
+ SUBXACT_EVENT_PRE_COMMIT_SUB
} SubXactEvent;
typedef void (*SubXactCallback) (SubXactEvent event, SubTransactionId mySubid,
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 591a432f54..70e67d9eb7 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -6150,7 +6150,7 @@ plpgsql_xact_cb(XactEvent event, void *arg)
* expect the regular abort recovery procedures to release everything of
* interest.
*/
- if (event != XACT_EVENT_ABORT)
+ if (event == XACT_EVENT_COMMIT || event == XACT_EVENT_PREPARE)
{
/* Shouldn't be any econtext stack entries left at commit */
Assert(simple_econtext_stack == NULL);
@@ -6159,7 +6159,7 @@ plpgsql_xact_cb(XactEvent event, void *arg)
FreeExecutorState(simple_eval_estate);
simple_eval_estate = NULL;
}
- else
+ else if (event == XACT_EVENT_ABORT)
{
simple_econtext_stack = NULL;
simple_eval_estate = NULL;
@@ -6178,19 +6178,19 @@ void
plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid,
SubTransactionId parentSubid, void *arg)
{
- if (event == SUBXACT_EVENT_START_SUB)
- return;
-
- while (simple_econtext_stack != NULL &&
- simple_econtext_stack->xact_subxid == mySubid)
+ if (event == SUBXACT_EVENT_COMMIT_SUB || event == SUBXACT_EVENT_ABORT_SUB)
{
- SimpleEcontextStackEntry *next;
+ while (simple_econtext_stack != NULL &&
+ simple_econtext_stack->xact_subxid == mySubid)
+ {
+ SimpleEcontextStackEntry *next;
- FreeExprContext(simple_econtext_stack->stack_econtext,
- (event == SUBXACT_EVENT_COMMIT_SUB));
- next = simple_econtext_stack->next;
- pfree(simple_econtext_stack);
- simple_econtext_stack = next;
+ FreeExprContext(simple_econtext_stack->stack_econtext,
+ (event == SUBXACT_EVENT_COMMIT_SUB));
+ next = simple_econtext_stack->next;
+ pfree(simple_econtext_stack);
+ simple_econtext_stack = next;
+ }
}
}