From fa0e318f947878b2ae53a12595f4520d9f082f91 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 30 May 2007 21:01:39 +0000
Subject: [PATCH] Fix overly-strict sanity check in BeginInternalSubTransaction
 that made it fail when used in a deferred trigger.  Bug goes back to 8.0; no
 doubt the reason it hadn't been noticed is that we've been discouraging use
 of user-defined constraint triggers.  Per report from Frank van Vugt.

---
 src/backend/access/transam/xact.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index c16b4fa6be9..000c72f8de1 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.243 2007/05/27 03:50:39 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.244 2007/05/30 21:01:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3348,10 +3348,11 @@ RollbackToSavepoint(List *options)
 
 /*
  * BeginInternalSubTransaction
- *		This is the same as DefineSavepoint except it allows TBLOCK_STARTED
- *		state, and therefore it can safely be used in a function that might
- *		be called when not inside a BEGIN block.  Also, we automatically
- *		cycle through CommitTransactionCommand/StartTransactionCommand
+ *		This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
+ *		TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
+ *		used in functions that might be called when not inside a BEGIN block
+ *		or when running deferred triggers at COMMIT/PREPARE time.  Also, it
+ *		automatically does CommitTransactionCommand/StartTransactionCommand
  *		instead of expecting the caller to do it.
  */
 void
@@ -3363,6 +3364,8 @@ BeginInternalSubTransaction(char *name)
 	{
 		case TBLOCK_STARTED:
 		case TBLOCK_INPROGRESS:
+		case TBLOCK_END:
+		case TBLOCK_PREPARE:
 		case TBLOCK_SUBINPROGRESS:
 			/* Normal subtransaction start */
 			PushTransaction();
@@ -3380,7 +3383,6 @@ BeginInternalSubTransaction(char *name)
 		case TBLOCK_DEFAULT:
 		case TBLOCK_BEGIN:
 		case TBLOCK_SUBBEGIN:
-		case TBLOCK_END:
 		case TBLOCK_SUBEND:
 		case TBLOCK_ABORT:
 		case TBLOCK_SUBABORT:
@@ -3390,7 +3392,6 @@ BeginInternalSubTransaction(char *name)
 		case TBLOCK_SUBABORT_PENDING:
 		case TBLOCK_SUBRESTART:
 		case TBLOCK_SUBABORT_RESTART:
-		case TBLOCK_PREPARE:
 			elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
 				 BlockStateAsString(s->blockState));
 			break;
-- 
GitLab