v1-dont-use-SetConfigOption-for-is-superuser.patch
text/x-diff
Filename: v1-dont-use-SetConfigOption-for-is-superuser.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
Series: patch v1
| File | + | − |
|---|---|---|
| src/backend/commands/variable.c | 13 | 0 |
| src/backend/utils/init/miscinit.c | 4 | 11 |
| src/backend/utils/misc/guc.c | 9 | 0 |
| src/backend/utils/misc/guc_tables.c | 4 | 3 |
| src/include/utils/guc.h | 1 | 0 |
| src/include/utils/guc_hooks.h | 1 | 0 |
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 6202c5ebe4..7b98b03c10 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -1026,6 +1026,19 @@ show_role(void)
return role_string ? role_string : "none";
}
+const char *
+show_is_superuser(void)
+{
+ /*
+ * Report the real value of current_role_is_superuser, not the
+ * possibly-stale value in the GUC mechanism. The reason we do things
+ * this way is to avoid the overhead and extra failure modes that'd be
+ * involved in using SetConfigOption to set is_superuser every time we
+ * update the session_authorization or role GUCs.
+ */
+ return current_role_is_superuser ? "on" : "off";
+}
+
/*
* PATH VARIABLES
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 537d92c0cf..4052b16ecb 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -822,9 +822,7 @@ InitializeSessionUserId(const char *rolename, Oid roleid, bool bypass_login_chec
/* Record username and superuser status as GUC settings too */
SetConfigOption("session_authorization", rname,
PGC_BACKEND, PGC_S_OVERRIDE);
- SetConfigOption("is_superuser",
- is_superuser ? "on" : "off",
- PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
+ current_role_is_superuser = is_superuser;
ReleaseSysCache(roleTup);
}
@@ -854,8 +852,7 @@ InitializeSessionUserIdStandalone(void)
* Since we don't, C code will get NULL, and current_setting() will get an
* empty string.
*/
- SetConfigOption("is_superuser", "on",
- PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
+ current_role_is_superuser = true;
}
/*
@@ -909,9 +906,7 @@ SetSessionAuthorization(Oid userid, bool is_superuser)
{
SetSessionUserId(userid, is_superuser);
- SetConfigOption("is_superuser",
- is_superuser ? "on" : "off",
- PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
+ current_role_is_superuser = is_superuser;
}
/*
@@ -966,9 +961,7 @@ SetCurrentRoleId(Oid roleid, bool is_superuser)
SetOuterUserId(roleid);
- SetConfigOption("is_superuser",
- is_superuser ? "on" : "off",
- PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
+ current_role_is_superuser = is_superuser;
}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 0c593b81b4..f99975ed61 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2610,6 +2610,15 @@ ReportChangedGUCOptions(void)
SetConfigOption("in_hot_standby", "false",
PGC_INTERNAL, PGC_S_OVERRIDE);
+ /*
+ * Also, check to see if we need to update the is_superuser GUC. This is
+ * to queue a guc_report_list entry if needed.
+ */
+ if (current_role_is_superuser != current_role_is_superuser_guc)
+ SetConfigOption("is_superuser",
+ current_role_is_superuser ? "on" : "off",
+ PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
+
/* Transmit new values of interesting variables */
slist_foreach_modify(iter, &guc_report_list)
{
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index c0a52cdcc3..cf09c59e40 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -516,7 +516,8 @@ bool check_function_bodies = true;
*/
static bool default_with_oids = false;
-bool current_role_is_superuser;
+bool current_role_is_superuser; /* this is the "real" status */
+bool current_role_is_superuser_guc; /* but the GUC table points here */
int log_min_error_statement = ERROR;
int log_min_messages = WARNING;
@@ -1017,9 +1018,9 @@ struct config_bool ConfigureNamesBool[] =
NULL,
GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
},
- ¤t_role_is_superuser,
+ ¤t_role_is_superuser_guc,
false,
- NULL, NULL, NULL
+ NULL, NULL, show_is_superuser
},
{
/*
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 4129ea37ee..efdb4fc815 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -260,6 +260,7 @@ extern PGDLLIMPORT char *event_source;
extern PGDLLIMPORT bool check_function_bodies;
extern PGDLLIMPORT bool current_role_is_superuser;
+extern PGDLLIMPORT bool current_role_is_superuser_guc; /* don't use this */
extern PGDLLIMPORT bool AllowAlterSystem;
extern PGDLLIMPORT bool log_duration;
diff --git a/src/include/utils/guc_hooks.h b/src/include/utils/guc_hooks.h
index 5813dba0a2..d10eb44a2c 100644
--- a/src/include/utils/guc_hooks.h
+++ b/src/include/utils/guc_hooks.h
@@ -121,6 +121,7 @@ extern void assign_recovery_target_xid(const char *newval, void *extra);
extern bool check_role(char **newval, void **extra, GucSource source);
extern void assign_role(const char *newval, void *extra);
extern const char *show_role(void);
+extern const char *show_is_superuser(void);
extern bool check_restrict_nonsystem_relation_kind(char **newval, void **extra,
GucSource source);
extern void assign_restrict_nonsystem_relation_kind(const char *newval, void *extra);