diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 9a1da59..28ab39f 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -981,8 +981,22 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
 
 	if (fcache->proconfig)
 		AtEOXact_GUC(true, save_nestlevel);
+
 	if (OidIsValid(fcache->userid))
-		SetUserIdAndSecContext(save_userid, save_sec_context);
+	{
+		Oid	current_userid;
+		int	current_sec_context;
+		/*
+		 * If the called function stack used SET ROLE to change CurrentUserId
+		 * then do not revert the setting back to the saved user.
+		 */
+		GetUserIdAndSecContext(&current_userid, &current_sec_context);
+
+		if(fcache->userid == current_userid)
+			SetUserIdAndSecContext(save_userid, save_sec_context);
+		else
+			SetUserIdAndSecContext(current_userid, save_sec_context);
+	}
 
 	return result;
 }
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 359edee..a565836 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -313,7 +313,7 @@ GetOuterUserId(void)
 static void
 SetOuterUserId(Oid userid)
 {
-	AssertState(SecurityRestrictionContext == 0);
+	AssertState(!InSecurityRestrictedOperation());
 	AssertArg(OidIsValid(userid));
 	OuterUserId = userid;
 
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index b530720..4a54df3 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2381,7 +2381,8 @@ static struct config_string ConfigureNamesString[] =
 		{"session_authorization", PGC_USERSET, UNGROUPED,
 			gettext_noop("Sets the session user name."),
 			NULL,
-			GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
+			GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+			| GUC_NOT_WHILE_SEC_REST | GUC_NOT_WHILE_USER_CHANGE
 		},
 		&session_authorization_string,
 		NULL, assign_session_authorization, show_session_authorization
@@ -4747,20 +4748,20 @@ set_config_option(const char *name, const char *value,
 	 * we prohibit changing these in a security-restricted operation because
 	 * otherwise RESET could be used to regain the session user's privileges.
 	 */
-	if (record->flags & GUC_NOT_WHILE_SEC_REST)
+	if (record->flags & GUC_NOT_WHILE_USER_CHANGE)
 	{
 		if (InLocalUserIdChange())
 		{
-			/*
-			 * Phrasing of this error message is historical, but it's the
-			 * most common case.
-			 */
 			ereport(elevel,
 					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-					 errmsg("cannot set parameter \"%s\" within security-definer function",
+					 errmsg("cannot set parameter \"%s\" while user-id changed temporarily",
 							name)));
 			return false;
 		}
+	}
+
+	if (record->flags & GUC_NOT_WHILE_SEC_REST)
+	{
 		if (InSecurityRestrictedOperation())
 		{
 			ereport(elevel,
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 9c95b60..469c787 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -149,7 +149,9 @@ typedef enum
 #define GUC_UNIT_MIN			0x4000	/* value is in minutes */
 #define GUC_UNIT_TIME			0x7000	/* mask for MS, S, MIN */
 
-#define GUC_NOT_WHILE_SEC_REST	0x8000	/* can't set if security restricted */
+#define GUC_NOT_WHILE_SEC_REST		0x08000	/* can't set if security restricted */
+#define GUC_NOT_WHILE_USER_CHANGE	0x10000	/* can't set if current-user-id temporarily changed */
+
 
 /* GUC vars that are actually declared in guc.c, rather than elsewhere */
 extern bool log_duration;
