Avoid an Assert failure if OuterUserId hasn't been set yet during
authorTom Lane <[email protected]>
Wed, 17 Aug 2005 22:14:34 +0000 (22:14 +0000)
committerTom Lane <[email protected]>
Wed, 17 Aug 2005 22:14:34 +0000 (22:14 +0000)
AbortTransaction.  This can happen if a backend's InitPostgres transaction
fails (eg, because the given username is invalid).  Per Alvaro.

src/backend/access/transam/xact.c
src/backend/utils/init/miscinit.c
src/include/miscadmin.h

index cb7e3b6ec58663f24ad51d57ccce4231ed6ab16e..d9fe840ef689f7a1800491c8900e900866575e04 100644 (file)
@@ -1877,8 +1877,8 @@ AbortTransaction(void)
 
        /*
         * Reset user id which might have been changed transiently.  We cannot
-        * use s->currentUser, but must get the session outer-level userid from
-        * miscinit.c.
+        * use s->currentUser, since it may not be set yet; instead rely on
+        * internal state of miscinit.c.
         *
         * (Note: it is not necessary to restore session authorization here
         * because that can only be changed via GUC, and GUC will take care of
@@ -1886,7 +1886,7 @@ AbortTransaction(void)
         * DEFINER function could send control here with the wrong current
         * userid.)
         */
-       SetUserId(GetOuterUserId());
+       AtAbort_UserId();
 
        /*
         * do abort processing
index fe5aa8908e230a9a62f6b2afae7a91e4f6bbfefe..b27cc26ca79ace413390f94916529aa7cb9636f0 100644 (file)
@@ -286,7 +286,7 @@ make_absolute_path(const char *path)
  * OuterUserId is the current user ID in effect at the "outer level" (outside
  * any transaction or function).  This is initially the same as SessionUserId,
  * but can be changed by SET ROLE to any role that SessionUserId is a
- * member of.  We store this mainly so that AbortTransaction knows what to
+ * member of.  We store this mainly so that AtAbort_UserId knows what to
  * reset CurrentUserId to.
  *
  * CurrentUserId is the current effective user ID; this is the one to use
@@ -496,6 +496,21 @@ InitializeSessionUserIdStandalone(void)
 }
 
 
+/*
+ * Reset effective userid during AbortTransaction
+ *
+ * This is essentially SetUserId(GetOuterUserId()), but without the Asserts.
+ * The reason is that if a backend's InitPostgres transaction fails (eg,
+ * because an invalid user name was given), we have to be able to get through
+ * AbortTransaction without asserting.
+ */
+void
+AtAbort_UserId(void)
+{
+       CurrentUserId = OuterUserId;
+}
+
+
 /*
  * Change session auth ID while running
  *
index c72e5bc28e86e992b47240414af3d4bafe081b15..70ff4ef9de50ee885fd0fb127896ae83c40a7a98 100644 (file)
@@ -235,6 +235,7 @@ extern Oid GetOuterUserId(void);
 extern Oid GetSessionUserId(void);
 extern void InitializeSessionUserId(const char *rolename);
 extern void InitializeSessionUserIdStandalone(void);
+extern void AtAbort_UserId(void);
 extern void SetSessionAuthorization(Oid userid, bool is_superuser);
 extern Oid GetCurrentRoleId(void);
 extern void SetCurrentRoleId(Oid roleid, bool is_superuser);