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.
This commit is contained in:
parent
09e196e453
commit
9f5836d224
|
@ -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)
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
|
|
@ -3861,8 +3861,10 @@ static void
|
||||||
InitializeOneGUCOption(struct config_generic * gconf)
|
InitializeOneGUCOption(struct config_generic * gconf)
|
||||||
{
|
{
|
||||||
gconf->status = 0;
|
gconf->status = 0;
|
||||||
gconf->reset_source = PGC_S_DEFAULT;
|
|
||||||
gconf->source = PGC_S_DEFAULT;
|
gconf->source = PGC_S_DEFAULT;
|
||||||
|
gconf->reset_source = PGC_S_DEFAULT;
|
||||||
|
gconf->scontext = PGC_INTERNAL;
|
||||||
|
gconf->reset_scontext = PGC_INTERNAL;
|
||||||
gconf->stack = NULL;
|
gconf->stack = NULL;
|
||||||
gconf->extra = NULL;
|
gconf->extra = NULL;
|
||||||
gconf->sourcefile = NULL;
|
gconf->sourcefile = NULL;
|
||||||
|
@ -4213,6 +4215,7 @@ ResetAllOptions(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
gconf->source = gconf->reset_source;
|
gconf->source = gconf->reset_source;
|
||||||
|
gconf->scontext = gconf->reset_scontext;
|
||||||
|
|
||||||
if (gconf->flags & GUC_REPORT)
|
if (gconf->flags & GUC_REPORT)
|
||||||
ReportGUCOption(gconf);
|
ReportGUCOption(gconf);
|
||||||
|
@ -4254,6 +4257,7 @@ push_old_value(struct config_generic * gconf, GucAction action)
|
||||||
if (stack->state == GUC_SET)
|
if (stack->state == GUC_SET)
|
||||||
{
|
{
|
||||||
/* SET followed by SET LOCAL, remember SET's value */
|
/* SET followed by SET LOCAL, remember SET's value */
|
||||||
|
stack->masked_scontext = gconf->scontext;
|
||||||
set_stack_value(gconf, &stack->masked);
|
set_stack_value(gconf, &stack->masked);
|
||||||
stack->state = GUC_SET_LOCAL;
|
stack->state = GUC_SET_LOCAL;
|
||||||
}
|
}
|
||||||
|
@ -4291,6 +4295,7 @@ push_old_value(struct config_generic * gconf, GucAction action)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
stack->source = gconf->source;
|
stack->source = gconf->source;
|
||||||
|
stack->scontext = gconf->scontext;
|
||||||
set_stack_value(gconf, &stack->prior);
|
set_stack_value(gconf, &stack->prior);
|
||||||
|
|
||||||
gconf->stack = stack;
|
gconf->stack = stack;
|
||||||
|
@ -4431,6 +4436,7 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
|
||||||
if (prev->state == GUC_SET)
|
if (prev->state == GUC_SET)
|
||||||
{
|
{
|
||||||
/* LOCAL migrates down */
|
/* LOCAL migrates down */
|
||||||
|
prev->masked_scontext = stack->scontext;
|
||||||
prev->masked = stack->prior;
|
prev->masked = stack->prior;
|
||||||
prev->state = GUC_SET_LOCAL;
|
prev->state = GUC_SET_LOCAL;
|
||||||
}
|
}
|
||||||
|
@ -4445,6 +4451,7 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
|
||||||
/* prior state at this level no longer wanted */
|
/* prior state at this level no longer wanted */
|
||||||
discard_stack_value(gconf, &stack->prior);
|
discard_stack_value(gconf, &stack->prior);
|
||||||
/* copy down the masked state */
|
/* copy down the masked state */
|
||||||
|
prev->masked_scontext = stack->masked_scontext;
|
||||||
if (prev->state == GUC_SET_LOCAL)
|
if (prev->state == GUC_SET_LOCAL)
|
||||||
discard_stack_value(gconf, &prev->masked);
|
discard_stack_value(gconf, &prev->masked);
|
||||||
prev->masked = stack->masked;
|
prev->masked = stack->masked;
|
||||||
|
@ -4460,16 +4467,19 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
|
||||||
/* Perform appropriate restoration of the stacked value */
|
/* Perform appropriate restoration of the stacked value */
|
||||||
config_var_value newvalue;
|
config_var_value newvalue;
|
||||||
GucSource newsource;
|
GucSource newsource;
|
||||||
|
GucContext newscontext;
|
||||||
|
|
||||||
if (restoreMasked)
|
if (restoreMasked)
|
||||||
{
|
{
|
||||||
newvalue = stack->masked;
|
newvalue = stack->masked;
|
||||||
newsource = PGC_S_SESSION;
|
newsource = PGC_S_SESSION;
|
||||||
|
newscontext = stack->masked_scontext;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newvalue = stack->prior;
|
newvalue = stack->prior;
|
||||||
newsource = stack->source;
|
newsource = stack->source;
|
||||||
|
newscontext = stack->scontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (gconf->vartype)
|
switch (gconf->vartype)
|
||||||
|
@ -4581,7 +4591,9 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
|
||||||
set_extra_field(gconf, &(stack->prior.extra), NULL);
|
set_extra_field(gconf, &(stack->prior.extra), NULL);
|
||||||
set_extra_field(gconf, &(stack->masked.extra), NULL);
|
set_extra_field(gconf, &(stack->masked.extra), NULL);
|
||||||
|
|
||||||
|
/* And restore source information */
|
||||||
gconf->source = newsource;
|
gconf->source = newsource;
|
||||||
|
gconf->scontext = newscontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish popping the state stack */
|
/* Finish popping the state stack */
|
||||||
|
@ -5255,6 +5267,7 @@ set_config_option(const char *name, const char *value,
|
||||||
newval = conf->reset_val;
|
newval = conf->reset_val;
|
||||||
newextra = conf->reset_extra;
|
newextra = conf->reset_extra;
|
||||||
source = conf->gen.reset_source;
|
source = conf->gen.reset_source;
|
||||||
|
context = conf->gen.reset_scontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prohibitValueChange)
|
if (prohibitValueChange)
|
||||||
|
@ -5282,6 +5295,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &conf->gen.extra,
|
set_extra_field(&conf->gen, &conf->gen.extra,
|
||||||
newextra);
|
newextra);
|
||||||
conf->gen.source = source;
|
conf->gen.source = source;
|
||||||
|
conf->gen.scontext = context;
|
||||||
}
|
}
|
||||||
if (makeDefault)
|
if (makeDefault)
|
||||||
{
|
{
|
||||||
|
@ -5293,6 +5307,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &conf->reset_extra,
|
set_extra_field(&conf->gen, &conf->reset_extra,
|
||||||
newextra);
|
newextra);
|
||||||
conf->gen.reset_source = source;
|
conf->gen.reset_source = source;
|
||||||
|
conf->gen.reset_scontext = context;
|
||||||
}
|
}
|
||||||
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
||||||
{
|
{
|
||||||
|
@ -5302,6 +5317,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &stack->prior.extra,
|
set_extra_field(&conf->gen, &stack->prior.extra,
|
||||||
newextra);
|
newextra);
|
||||||
stack->source = source;
|
stack->source = source;
|
||||||
|
stack->scontext = context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5355,6 +5371,7 @@ set_config_option(const char *name, const char *value,
|
||||||
newval = conf->reset_val;
|
newval = conf->reset_val;
|
||||||
newextra = conf->reset_extra;
|
newextra = conf->reset_extra;
|
||||||
source = conf->gen.reset_source;
|
source = conf->gen.reset_source;
|
||||||
|
context = conf->gen.reset_scontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prohibitValueChange)
|
if (prohibitValueChange)
|
||||||
|
@ -5382,6 +5399,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &conf->gen.extra,
|
set_extra_field(&conf->gen, &conf->gen.extra,
|
||||||
newextra);
|
newextra);
|
||||||
conf->gen.source = source;
|
conf->gen.source = source;
|
||||||
|
conf->gen.scontext = context;
|
||||||
}
|
}
|
||||||
if (makeDefault)
|
if (makeDefault)
|
||||||
{
|
{
|
||||||
|
@ -5393,6 +5411,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &conf->reset_extra,
|
set_extra_field(&conf->gen, &conf->reset_extra,
|
||||||
newextra);
|
newextra);
|
||||||
conf->gen.reset_source = source;
|
conf->gen.reset_source = source;
|
||||||
|
conf->gen.reset_scontext = context;
|
||||||
}
|
}
|
||||||
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
||||||
{
|
{
|
||||||
|
@ -5402,6 +5421,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &stack->prior.extra,
|
set_extra_field(&conf->gen, &stack->prior.extra,
|
||||||
newextra);
|
newextra);
|
||||||
stack->source = source;
|
stack->source = source;
|
||||||
|
stack->scontext = context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5452,6 +5472,7 @@ set_config_option(const char *name, const char *value,
|
||||||
newval = conf->reset_val;
|
newval = conf->reset_val;
|
||||||
newextra = conf->reset_extra;
|
newextra = conf->reset_extra;
|
||||||
source = conf->gen.reset_source;
|
source = conf->gen.reset_source;
|
||||||
|
context = conf->gen.reset_scontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prohibitValueChange)
|
if (prohibitValueChange)
|
||||||
|
@ -5479,6 +5500,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &conf->gen.extra,
|
set_extra_field(&conf->gen, &conf->gen.extra,
|
||||||
newextra);
|
newextra);
|
||||||
conf->gen.source = source;
|
conf->gen.source = source;
|
||||||
|
conf->gen.scontext = context;
|
||||||
}
|
}
|
||||||
if (makeDefault)
|
if (makeDefault)
|
||||||
{
|
{
|
||||||
|
@ -5490,6 +5512,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &conf->reset_extra,
|
set_extra_field(&conf->gen, &conf->reset_extra,
|
||||||
newextra);
|
newextra);
|
||||||
conf->gen.reset_source = source;
|
conf->gen.reset_source = source;
|
||||||
|
conf->gen.reset_scontext = context;
|
||||||
}
|
}
|
||||||
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
||||||
{
|
{
|
||||||
|
@ -5499,6 +5522,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &stack->prior.extra,
|
set_extra_field(&conf->gen, &stack->prior.extra,
|
||||||
newextra);
|
newextra);
|
||||||
stack->source = source;
|
stack->source = source;
|
||||||
|
stack->scontext = context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5567,6 +5591,7 @@ set_config_option(const char *name, const char *value,
|
||||||
newval = conf->reset_val;
|
newval = conf->reset_val;
|
||||||
newextra = conf->reset_extra;
|
newextra = conf->reset_extra;
|
||||||
source = conf->gen.reset_source;
|
source = conf->gen.reset_source;
|
||||||
|
context = conf->gen.reset_scontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prohibitValueChange)
|
if (prohibitValueChange)
|
||||||
|
@ -5596,6 +5621,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &conf->gen.extra,
|
set_extra_field(&conf->gen, &conf->gen.extra,
|
||||||
newextra);
|
newextra);
|
||||||
conf->gen.source = source;
|
conf->gen.source = source;
|
||||||
|
conf->gen.scontext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (makeDefault)
|
if (makeDefault)
|
||||||
|
@ -5608,6 +5634,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &conf->reset_extra,
|
set_extra_field(&conf->gen, &conf->reset_extra,
|
||||||
newextra);
|
newextra);
|
||||||
conf->gen.reset_source = source;
|
conf->gen.reset_source = source;
|
||||||
|
conf->gen.reset_scontext = context;
|
||||||
}
|
}
|
||||||
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
||||||
{
|
{
|
||||||
|
@ -5618,6 +5645,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &stack->prior.extra,
|
set_extra_field(&conf->gen, &stack->prior.extra,
|
||||||
newextra);
|
newextra);
|
||||||
stack->source = source;
|
stack->source = source;
|
||||||
|
stack->scontext = context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5673,6 +5701,7 @@ set_config_option(const char *name, const char *value,
|
||||||
newval = conf->reset_val;
|
newval = conf->reset_val;
|
||||||
newextra = conf->reset_extra;
|
newextra = conf->reset_extra;
|
||||||
source = conf->gen.reset_source;
|
source = conf->gen.reset_source;
|
||||||
|
context = conf->gen.reset_scontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prohibitValueChange)
|
if (prohibitValueChange)
|
||||||
|
@ -5700,6 +5729,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &conf->gen.extra,
|
set_extra_field(&conf->gen, &conf->gen.extra,
|
||||||
newextra);
|
newextra);
|
||||||
conf->gen.source = source;
|
conf->gen.source = source;
|
||||||
|
conf->gen.scontext = context;
|
||||||
}
|
}
|
||||||
if (makeDefault)
|
if (makeDefault)
|
||||||
{
|
{
|
||||||
|
@ -5711,6 +5741,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &conf->reset_extra,
|
set_extra_field(&conf->gen, &conf->reset_extra,
|
||||||
newextra);
|
newextra);
|
||||||
conf->gen.reset_source = source;
|
conf->gen.reset_source = source;
|
||||||
|
conf->gen.reset_scontext = context;
|
||||||
}
|
}
|
||||||
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
||||||
{
|
{
|
||||||
|
@ -5720,6 +5751,7 @@ set_config_option(const char *name, const char *value,
|
||||||
set_extra_field(&conf->gen, &stack->prior.extra,
|
set_extra_field(&conf->gen, &stack->prior.extra,
|
||||||
newextra);
|
newextra);
|
||||||
stack->source = source;
|
stack->source = source;
|
||||||
|
stack->scontext = context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6252,7 +6284,6 @@ define_custom_variable(struct config_generic * variable)
|
||||||
const char **nameAddr = &name;
|
const char **nameAddr = &name;
|
||||||
const char *value;
|
const char *value;
|
||||||
struct config_string *pHolder;
|
struct config_string *pHolder;
|
||||||
GucContext phcontext;
|
|
||||||
struct config_generic **res;
|
struct config_generic **res;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -6298,56 +6329,6 @@ define_custom_variable(struct config_generic * variable)
|
||||||
*/
|
*/
|
||||||
*res = variable;
|
*res = variable;
|
||||||
|
|
||||||
/*
|
|
||||||
* Infer context for assignment based on source of existing value. We
|
|
||||||
* can't tell this with exact accuracy, but we can at least do something
|
|
||||||
* reasonable in typical cases.
|
|
||||||
*/
|
|
||||||
switch (pHolder->gen.source)
|
|
||||||
{
|
|
||||||
case PGC_S_DEFAULT:
|
|
||||||
case PGC_S_DYNAMIC_DEFAULT:
|
|
||||||
case PGC_S_ENV_VAR:
|
|
||||||
case PGC_S_FILE:
|
|
||||||
case PGC_S_ARGV:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we got past the check in init_custom_variable, we can safely
|
|
||||||
* assume that any existing value for a PGC_POSTMASTER variable
|
|
||||||
* was set in postmaster context.
|
|
||||||
*/
|
|
||||||
if (variable->context == PGC_POSTMASTER)
|
|
||||||
phcontext = PGC_POSTMASTER;
|
|
||||||
else
|
|
||||||
phcontext = PGC_SIGHUP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PGC_S_DATABASE:
|
|
||||||
case PGC_S_USER:
|
|
||||||
case PGC_S_DATABASE_USER:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The existing value came from an ALTER ROLE/DATABASE SET
|
|
||||||
* command. We can assume that at the time the command was issued,
|
|
||||||
* we checked that the issuing user was superuser if the variable
|
|
||||||
* requires superuser privileges to set. So it's safe to use
|
|
||||||
* SUSET context here.
|
|
||||||
*/
|
|
||||||
phcontext = PGC_SUSET;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PGC_S_CLIENT:
|
|
||||||
case PGC_S_SESSION:
|
|
||||||
default:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We must assume that the value came from an untrusted user, even
|
|
||||||
* if the current_user is a superuser.
|
|
||||||
*/
|
|
||||||
phcontext = PGC_USERSET;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Assign the string value stored in the placeholder to the real variable.
|
* Assign the string value stored in the placeholder to the real variable.
|
||||||
*
|
*
|
||||||
|
@ -6360,8 +6341,8 @@ define_custom_variable(struct config_generic * variable)
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
if (set_config_option(name, value,
|
if (set_config_option(name, value,
|
||||||
phcontext, pHolder->gen.source,
|
pHolder->gen.scontext, pHolder->gen.source,
|
||||||
GUC_ACTION_SET, true) > 0)
|
GUC_ACTION_SET, true) != 0)
|
||||||
{
|
{
|
||||||
/* Also copy over any saved source-location information */
|
/* Also copy over any saved source-location information */
|
||||||
if (pHolder->gen.sourcefile)
|
if (pHolder->gen.sourcefile)
|
||||||
|
@ -7284,6 +7265,7 @@ _ShowOption(struct config_generic * record, bool use_units)
|
||||||
* variable name, string, null terminated
|
* variable name, string, null terminated
|
||||||
* variable value, string, null terminated
|
* variable value, string, null terminated
|
||||||
* variable source, integer
|
* variable source, integer
|
||||||
|
* variable scontext, integer
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
write_one_nondefault_variable(FILE *fp, struct config_generic * gconf)
|
write_one_nondefault_variable(FILE *fp, struct config_generic * gconf)
|
||||||
|
@ -7319,8 +7301,7 @@ write_one_nondefault_variable(FILE *fp, struct config_generic * gconf)
|
||||||
{
|
{
|
||||||
struct config_real *conf = (struct config_real *) gconf;
|
struct config_real *conf = (struct config_real *) gconf;
|
||||||
|
|
||||||
/* Could lose precision here? */
|
fprintf(fp, "%.17g", *conf->variable);
|
||||||
fprintf(fp, "%f", *conf->variable);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -7344,7 +7325,8 @@ write_one_nondefault_variable(FILE *fp, struct config_generic * gconf)
|
||||||
|
|
||||||
fputc(0, fp);
|
fputc(0, fp);
|
||||||
|
|
||||||
fwrite(&gconf->source, sizeof(gconf->source), 1, fp);
|
fwrite(&gconf->source, 1, sizeof(gconf->source), fp);
|
||||||
|
fwrite(&gconf->scontext, 1, sizeof(gconf->scontext), fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -7436,7 +7418,8 @@ read_nondefault_variables(void)
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *varname,
|
char *varname,
|
||||||
*varvalue;
|
*varvalue;
|
||||||
int varsource;
|
GucSource varsource;
|
||||||
|
GucContext varscontext;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open file
|
* Open file
|
||||||
|
@ -7464,11 +7447,14 @@ read_nondefault_variables(void)
|
||||||
elog(FATAL, "failed to locate variable %s in exec config params file", varname);
|
elog(FATAL, "failed to locate variable %s in exec config params file", varname);
|
||||||
if ((varvalue = read_string_with_null(fp)) == NULL)
|
if ((varvalue = read_string_with_null(fp)) == NULL)
|
||||||
elog(FATAL, "invalid format of exec config params file");
|
elog(FATAL, "invalid format of exec config params file");
|
||||||
if (fread(&varsource, sizeof(varsource), 1, fp) == 0)
|
if (fread(&varsource, 1, sizeof(varsource), fp) != sizeof(varsource))
|
||||||
|
elog(FATAL, "invalid format of exec config params file");
|
||||||
|
if (fread(&varscontext, 1, sizeof(varscontext), fp) != sizeof(varscontext))
|
||||||
elog(FATAL, "invalid format of exec config params file");
|
elog(FATAL, "invalid format of exec config params file");
|
||||||
|
|
||||||
(void) set_config_option(varname, varvalue, record->context,
|
(void) set_config_option(varname, varvalue,
|
||||||
varsource, GUC_ACTION_SET, true);
|
varscontext, varsource,
|
||||||
|
GUC_ACTION_SET, true);
|
||||||
free(varname);
|
free(varname);
|
||||||
free(varvalue);
|
free(varvalue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
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 */
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- 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;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
-- 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
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
-- 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';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
-- 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") ';
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
-- 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';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
-- 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
|
||||||
|
|
Loading…
Reference in New Issue