Commit 9f5836d2 authored by Tom Lane's avatar Tom Lane

Remember the source GucContext for each GUC parameter.

We used to just remember the GucSource, but saving GucContext too provides
a little more information --- notably, whether a SET was done by a
superuser or regular user.  This allows us to rip out the fairly dodgy code
that define_custom_variable used to use to try to infer the context to
re-install a pre-existing setting with.  In particular, it now works for
a superuser to SET a extension's SUSET custom variable before loading the
associated extension, because GUC can remember whether the SET was done as
a superuser or not.  The plperl regression tests contain an example where
this is useful.
parent 09e196e4
...@@ -296,11 +296,7 @@ ProcessConfigFile(GucContext context) ...@@ -296,11 +296,7 @@ ProcessConfigFile(GucContext context)
GUC_ACTION_SET, true); GUC_ACTION_SET, true);
if (scres > 0) if (scres > 0)
{ {
/* variable was updated, so remember the source location */ /* variable was updated, so log the change if appropriate */
set_config_sourcefile(item->name, item->filename,
item->sourceline);
/* and log the change if appropriate */
if (pre_value) if (pre_value)
{ {
const char *post_value = GetConfigOption(item->name, true, false); const char *post_value = GetConfigOption(item->name, true, false);
...@@ -315,7 +311,17 @@ ProcessConfigFile(GucContext context) ...@@ -315,7 +311,17 @@ ProcessConfigFile(GucContext context)
} }
else if (scres == 0) else if (scres == 0)
error = true; error = true;
/* else no error but variable was not changed, do nothing */ /* else no error but variable's active value was not changed */
/*
* We should update source location unless there was an error, since
* even if the active value didn't change, the reset value might have.
* (In the postmaster, there won't be a difference, but it does matter
* in backends.)
*/
if (scres != 0)
set_config_sourcefile(item->name, item->filename,
item->sourceline);
if (pre_value) if (pre_value)
pfree(pre_value); pfree(pre_value);
......
This diff is collapsed.
...@@ -118,9 +118,11 @@ typedef struct guc_stack ...@@ -118,9 +118,11 @@ typedef struct guc_stack
int nest_level; /* nesting depth at which we made entry */ int nest_level; /* nesting depth at which we made entry */
GucStackState state; /* see enum above */ GucStackState state; /* see enum above */
GucSource source; /* source of the prior value */ GucSource source; /* source of the prior value */
/* masked value's source must be PGC_S_SESSION, so no need to store it */
GucContext scontext; /* context that set the prior value */
GucContext masked_scontext; /* context that set the masked value */
config_var_value prior; /* previous value of variable */ config_var_value prior; /* previous value of variable */
config_var_value masked; /* SET value in a GUC_SET_LOCAL entry */ config_var_value masked; /* SET value in a GUC_SET_LOCAL entry */
/* masked value's source must be PGC_S_SESSION, so no need to store it */
} GucStack; } GucStack;
/* /*
...@@ -143,21 +145,21 @@ struct config_generic ...@@ -143,21 +145,21 @@ struct config_generic
enum config_group group; /* to help organize variables by function */ enum config_group group; /* to help organize variables by function */
const char *short_desc; /* short desc. of this variable's purpose */ const char *short_desc; /* short desc. of this variable's purpose */
const char *long_desc; /* long desc. of this variable's purpose */ const char *long_desc; /* long desc. of this variable's purpose */
int flags; /* flag bits, see below */ int flags; /* flag bits, see guc.h */
/* variable fields, initialized at runtime: */ /* variable fields, initialized at runtime: */
enum config_type vartype; /* type of variable (set only at startup) */ enum config_type vartype; /* type of variable (set only at startup) */
int status; /* status bits, see below */ int status; /* status bits, see below */
GucSource reset_source; /* source of the reset_value */
GucSource source; /* source of the current actual value */ GucSource source; /* source of the current actual value */
GucSource reset_source; /* source of the reset_value */
GucContext scontext; /* context that set the current value */
GucContext reset_scontext; /* context that set the reset value */
GucStack *stack; /* stacked prior values */ GucStack *stack; /* stacked prior values */
void *extra; /* "extra" pointer for current actual value */ void *extra; /* "extra" pointer for current actual value */
char *sourcefile; /* file current setting is from (NULL if not char *sourcefile; /* file current setting is from (NULL if not
* file) */ * set in config file) */
int sourceline; /* line in source file */ int sourceline; /* line in source file */
}; };
/* bit values in flags field are defined in guc.h */
/* bit values in status field */ /* bit values in status field */
#define GUC_IS_IN_FILE 0x0001 /* found it in config file */ #define GUC_IS_IN_FILE 0x0001 /* found it in config file */
/* /*
......
-- test plperl.on_plperl_init errors are fatal -- test plperl.on_plperl_init errors are fatal
-- Must load plperl before we can set on_plperl_init -- This test tests setting on_plperl_init after loading plperl
LOAD 'plperl'; LOAD 'plperl';
SET SESSION plperl.on_plperl_init = ' system("/nonesuch") '; SET SESSION plperl.on_plperl_init = ' system("/nonesuch") ';
SHOW plperl.on_plperl_init; SHOW plperl.on_plperl_init;
......
-- test plperl.on_plperl_init via the shared hash -- test plperl.on_plperl_init via the shared hash
-- (must be done before plperl is first used) -- (must be done before plperl is first used)
-- Must load plperl before we can set on_plperl_init -- This test tests setting on_plperl_init before loading plperl
LOAD 'plperl';
-- testing on_plperl_init gets run, and that it can alter %_SHARED -- testing on_plperl_init gets run, and that it can alter %_SHARED
SET plperl.on_plperl_init = '$_SHARED{on_init} = 42'; SET plperl.on_plperl_init = '$_SHARED{on_init} = 42';
-- test the shared hash -- test the shared hash
......
-- Use ONLY plperlu tests here. For plperl/plerlu combined tests -- Use ONLY plperlu tests here. For plperl/plerlu combined tests
-- see plperl_plperlu.sql -- see plperl_plperlu.sql
-- Must load plperl before we can set on_plperlu_init -- This test tests setting on_plperlu_init after loading plperl
LOAD 'plperl'; LOAD 'plperl';
-- Test plperl.on_plperlu_init gets run -- Test plperl.on_plperlu_init gets run
SET plperl.on_plperlu_init = '$_SHARED{init} = 42'; SET plperl.on_plperlu_init = '$_SHARED{init} = 42';
......
-- test plperl.on_plperl_init errors are fatal -- test plperl.on_plperl_init errors are fatal
-- Must load plperl before we can set on_plperl_init -- This test tests setting on_plperl_init after loading plperl
LOAD 'plperl'; LOAD 'plperl';
SET SESSION plperl.on_plperl_init = ' system("/nonesuch") '; SET SESSION plperl.on_plperl_init = ' system("/nonesuch") ';
......
-- test plperl.on_plperl_init via the shared hash -- test plperl.on_plperl_init via the shared hash
-- (must be done before plperl is first used) -- (must be done before plperl is first used)
-- Must load plperl before we can set on_plperl_init -- This test tests setting on_plperl_init before loading plperl
LOAD 'plperl';
-- testing on_plperl_init gets run, and that it can alter %_SHARED -- testing on_plperl_init gets run, and that it can alter %_SHARED
SET plperl.on_plperl_init = '$_SHARED{on_init} = 42'; SET plperl.on_plperl_init = '$_SHARED{on_init} = 42';
......
-- Use ONLY plperlu tests here. For plperl/plerlu combined tests -- Use ONLY plperlu tests here. For plperl/plerlu combined tests
-- see plperl_plperlu.sql -- see plperl_plperlu.sql
-- Must load plperl before we can set on_plperlu_init -- This test tests setting on_plperlu_init after loading plperl
LOAD 'plperl'; LOAD 'plperl';
-- Test plperl.on_plperlu_init gets run -- Test plperl.on_plperlu_init gets run
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment