From cdfcd775ec30e02db5fb3f6dc9cd4d201bfb5bf5 Mon Sep 17 00:00:00 2001
From: Richard Guo <riguo@pivotal.io>
Date: Wed, 10 Oct 2018 06:43:26 +0000
Subject: [PATCH] Restore CurrentUserId only if 'prevUser' is valid.

During the first transaction starting phase within a backend, if there is an
'ereport' after setting transaction state but before saving CurrentUserId into
'prevUser' in TransactionStateData, 'prevUser' will remain as InvalidOid. Then
in AbortTransaction(), CurrentUserId is restored with 'prevUser'. As a result,
CurrentUserId will be InvalidOid in the rest of the session.

This patch fixes that by restoring CurrentUserId only if 'prevUser' is valid.
---
 src/backend/access/transam/xact.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 6cd00d9..6882399 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -2541,7 +2541,8 @@ AbortTransaction(void)
 	 * settings here because those can only be changed via GUC, and GUC will
 	 * take care of rolling them back if need be.)
 	 */
-	SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
+	if (s->prevUser != InvalidOid)
+		SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
 
 	/* If in parallel mode, clean up workers and exit parallel mode. */
 	if (IsInParallelMode())
@@ -4751,7 +4752,8 @@ AbortSubTransaction(void)
 	 * Reset user ID which might have been changed transiently.  (See notes in
 	 * AbortTransaction.)
 	 */
-	SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
+	if (s->prevUser != InvalidOid)
+		SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
 
 	/* Exit from parallel mode, if necessary. */
 	if (IsInParallelMode())
-- 
2.7.4

