aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/misc/guc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/misc/guc.c')
-rw-r--r--src/backend/utils/misc/guc.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 41f46491edb..6c74de41fc2 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -7265,6 +7265,8 @@ set_config_option(const char *name, const char *value,
case PGC_STRING:
{
struct config_string *conf = (struct config_string *) record;
+ GucContext orig_context = context;
+ GucSource orig_source = source;
#define newval (newval_union.stringval)
@@ -7348,6 +7350,35 @@ set_config_option(const char *name, const char *value,
newextra);
conf->gen.source = source;
conf->gen.scontext = context;
+
+ /*
+ * Ugly hack: during SET session_authorization, forcibly
+ * do SET ROLE NONE with the same context/source/etc, so
+ * that the effects will have identical lifespan. This is
+ * required by the SQL spec, and it's not possible to do
+ * it within the variable's check hook or assign hook
+ * because our APIs for those don't pass enough info.
+ * However, don't do it if is_reload: in that case we
+ * expect that if "role" isn't supposed to be default, it
+ * has been or will be set by a separate reload action.
+ *
+ * A fine point: for RESET session_authorization, we do
+ * "RESET role" not "SET ROLE NONE" (by passing down NULL
+ * rather than "none" for the value). This would have the
+ * same effects in typical cases, but if the reset value
+ * of "role" is not "none" it seems better to revert to
+ * that.
+ */
+ if (!is_reload &&
+ strcmp(conf->gen.name, "session_authorization") == 0)
+ (void) set_config_option("role",
+ value ? "none" : NULL,
+ orig_context,
+ orig_source,
+ action,
+ true,
+ elevel,
+ false);
}
if (makeDefault)
@@ -9946,18 +9977,13 @@ read_nondefault_variables(void)
* constants; a few, like server_encoding and lc_ctype, are handled specially
* outside the serialize/restore procedure. Therefore, SerializeGUCState()
* never sends these, and RestoreGUCState() never changes them.
- *
- * Role is a special variable in the sense that its current value can be an
- * invalid value and there are multiple ways by which that can happen (like
- * after setting the role, someone drops it). So we handle it outside of
- * serialize/restore machinery.
*/
static bool
can_skip_gucvar(struct config_generic *gconf)
{
return gconf->context == PGC_POSTMASTER ||
- gconf->context == PGC_INTERNAL || gconf->source == PGC_S_DEFAULT ||
- strcmp(gconf->name, "role") == 0;
+ gconf->context == PGC_INTERNAL ||
+ gconf->source == PGC_S_DEFAULT;
}
/*