提交 4237a7a5 编写于 作者: H Heikki Linnakangas

Remove the custom_variable_classes parameter.

In the upcoming PostgreSQL 9.0 merge, validating the custom variable
classes was causing grief in with the new plpgsql.variable_conflict GUC.
If you set that GUC after loading plpgsql in the QD, plpgsql migh still not
be loaded in QE processes. If the GUC was changed in the QD, the QD would
dispatch the new value to QE processes, which threw an error because the
'plpgsql' custom variable class was not defined.

In principle, we would have the same problem with any other GUC added by
a loadable module.

To fix,  cherry-pick upstream commit from 9.2, to remove the GUC and the
validation of custom variable classes altogether. Might as well do that
now, rather than make some temporary work-arounds, since it's a sensible
change that we'll get eventually from upstream anyway.

Upstream commit:

commit 1a00c0ef
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date:   Tue Oct 4 12:36:18 2011 -0400

    Remove the custom_variable_classes parameter.

    This variable provides only marginal error-prevention capability (since
    it can only check the prefix of a qualified GUC name), and the consensus
    is that that isn't worth the amount of hassle that maintaining the setting
    creates for DBAs.  So, let's just remove it.

    With this commit, the system will silently accept a value for any qualified
    GUC name at all, whether it has anything to do with any known extension or
    not.  (Unqualified names still have to match known built-in settings,
    though; and you will get a WARNING at extension load time if there's an
    unrecognized setting with that extension's prefix.)

    There's still some discussion ongoing about whether to tighten that up and
    if so how; but if we do come up with a solution, it's not likely to look
    anything like custom_variable_classes.
上级 d4ce0921
......@@ -54,9 +54,6 @@
<li>
<xref href="#cursor_tuple_fraction"/>
</li>
<li>
<xref href="#custom_variable_classes"/>
</li>
<li><xref href="#data_checksums" format="dita"/></li>
<li>
<xref href="#DateStyle"/>
......@@ -1279,35 +1276,6 @@
</table>
</body>
</topic>
<topic id="custom_variable_classes">
<title>custom_variable_classes</title>
<body>
<p>Specifies one or several class names to be used for custom variables. A custom variable is
a variable not normally known to the server but used by some add-on modules. Such variables
must have names consisting of a class name, a dot, and a variable name.</p>
<table id="custom_variable_classes_table">
<tgroup cols="3">
<colspec colnum="1" colname="col1" colwidth="1*"/>
<colspec colnum="2" colname="col2" colwidth="1*"/>
<colspec colnum="3" colname="col3" colwidth="1*"/>
<thead>
<row>
<entry colname="col1">Value Range</entry>
<entry colname="col2">Default</entry>
<entry colname="col3">Set Classifications</entry>
</row>
</thead>
<tbody>
<row>
<entry colname="col1">comma-separated list of class names</entry>
<entry colname="col2">unset</entry>
<entry colname="col3">local<p>system</p><p>restart</p></entry>
</row>
</tbody>
</tgroup>
</table>
</body>
</topic>
<topic id="data_checksums">
<title>data_checksums</title>
<body>
......
......@@ -21,7 +21,6 @@
<topicref href="guc-list.xml#cpu_operator_cost"/>
<topicref href="guc-list.xml#cpu_tuple_cost"/>
<topicref href="guc-list.xml#cursor_tuple_fraction"/>
<topicref href="guc-list.xml#custom_variable_classes"/>
<topicref href="guc-list.xml#data_checksums"/>
<topicref href="guc-list.xml#DateStyle"/>
<topicref href="guc-list.xml#db_user_namespace"/>
......
......@@ -136,7 +136,6 @@ ProcessConfigFile(GucContext context)
*head,
*tail;
char *cvc = NULL;
struct config_string *cvc_struct;
const char *envvar;
int i;
......@@ -168,41 +167,6 @@ ProcessConfigFile(GucContext context)
&head, &tail))
goto cleanup_list;
/*
* We need the proposed new value of custom_variable_classes to check
* custom variables with. ParseConfigFile ensured that if it's in
* the file, it's first in the list. But first check to see if we
* have an active value from the command line, which should override
* the file in any case. (Since there's no relevant env var, the
* only possible nondefault sources are the file and ARGV.)
*/
cvc_struct = (struct config_string *)
find_option("custom_variable_classes", false, elevel);
if (cvc_struct && cvc_struct->gen.reset_source > PGC_S_FILE)
{
cvc = guc_strdup(elevel, cvc_struct->reset_val);
if (cvc == NULL)
goto cleanup_list;
}
else if (head != NULL &&
guc_name_compare(head->name, "custom_variable_classes") == 0)
{
/*
* Need to canonicalize the value via the assign hook. Casting away
* const is a bit ugly, but we know the result is malloc'd.
*/
cvc = (char *) assign_custom_variable_classes(head->value,
false, PGC_S_FILE);
if (cvc == NULL)
{
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": \"%s\"",
head->name, head->value)));
goto cleanup_list;
}
}
/*
* Mark all extant GUC variables as not present in the config file.
* We need this so that we can tell below which ones have been removed
......@@ -232,6 +196,7 @@ ProcessConfigFile(GucContext context)
* of custom_variable_classes. If so, reject. We don't care
* which side is at fault.
*/
#if 0
if (!is_custom_class(item->name, sep - item->name, cvc))
{
ereport(elevel,
......@@ -240,6 +205,7 @@ ProcessConfigFile(GucContext context)
item->name)));
goto cleanup_list;
}
#endif
/*
* 2. There is no GUC entry. If we called set_config_option then
* it would make a placeholder, which we don't want to do yet,
......@@ -559,40 +525,6 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
pfree(opt_name);
pfree(opt_value);
}
else if (guc_name_compare(opt_name, "custom_variable_classes") == 0)
{
/*
* This variable must be processed first as it controls
* the validity of other variables; so it goes at the head
* of the result list. If we already found a value for it,
* replace with this one.
*/
item = *head_p;
if (item != NULL &&
guc_name_compare(item->name, "custom_variable_classes") == 0)
{
/* replace existing head item */
pfree(item->name);
pfree(item->value);
item->name = opt_name;
item->value = opt_value;
item->filename = pstrdup(config_file);
item->sourceline = ConfigFileLineno-1;
}
else
{
/* prepend to list */
item = palloc(sizeof *item);
item->name = opt_name;
item->value = opt_value;
item->filename = pstrdup(config_file);
item->sourceline = ConfigFileLineno-1;
item->next = *head_p;
*head_p = item;
if (*tail_p == NULL)
*tail_p = item;
}
}
else
{
/* ordinary variable, append to list */
......
......@@ -155,8 +155,6 @@ static bool assign_session_replication_role(int newval, bool doit,
GucSource source);
static const char *show_num_temp_buffers(void);
static bool assign_phony_autocommit(bool newval, bool doit, GucSource source);
static const char *assign_custom_variable_classes(const char *newval, bool doit,
GucSource source);
static bool assign_debug_assertions(bool newval, bool doit, GucSource source);
static bool assign_ssl(bool newval, bool doit, GucSource source);
static bool assign_stage_log_stats(bool newval, bool doit, GucSource source);
......@@ -426,7 +424,6 @@ static char *timezone_string;
static char *log_timezone_string;
static char *timezone_abbreviations_string;
static char *XactIsoLevel_string;
static char *custom_variable_classes;
static int max_function_args;
static int max_index_keys;
static int max_identifier_length;
......@@ -2609,16 +2606,6 @@ static struct config_string ConfigureNamesString[] =
"localhost", NULL, NULL
},
{
{"custom_variable_classes", PGC_SIGHUP, CUSTOM_OPTIONS,
gettext_noop("Sets the list of known custom variable classes."),
NULL,
GUC_LIST_INPUT | GUC_LIST_QUOTE
},
&custom_variable_classes,
NULL, assign_custom_variable_classes, NULL
},
{
{"data_directory", PGC_POSTMASTER, FILE_LOCATIONS,
gettext_noop("Sets the server's data directory."),
......@@ -3440,8 +3427,7 @@ add_guc_variable(struct config_generic * var, int elevel)
}
/*
* Create and add a placeholder variable. It's presumed to belong
* to a valid custom variable class at this point.
* Create and add a placeholder variable for a custom variable name.
*/
static struct config_generic *
add_placeholder_variable(const char *name, int elevel)
......@@ -3486,42 +3472,6 @@ add_placeholder_variable(const char *name, int elevel)
return gen;
}
/*
* Detect whether the portion of "name" before dotPos matches any custom
* variable class name listed in custom_var_classes. The latter must be
* formatted the way that assign_custom_variable_classes does it, ie,
* no whitespace. NULL is valid for custom_var_classes.
*/
static bool
is_custom_class(const char *name, int dotPos, const char *custom_var_classes)
{
bool result = false;
const char *ccs = custom_var_classes;
if (ccs != NULL)
{
const char *start = ccs;
for (;; ++ccs)
{
char c = *ccs;
if (c == '\0' || c == ',')
{
if (dotPos == ccs - start && strncmp(start, name, dotPos) == 0)
{
result = true;
break;
}
if (c == '\0')
break;
start = ccs + 1;
}
}
}
return result;
}
/*
* Look up option NAME. If it exists, return a pointer to its record,
* else return NULL. If create_placeholders is TRUE, we'll create a
......@@ -3562,13 +3512,9 @@ find_option(const char *name, bool create_placeholders, int elevel)
if (create_placeholders)
{
/*
* Check if the name is qualified, and if so, check if the qualifier
* matches any custom variable class. If so, add a placeholder.
* Check if the name is qualified, and if so, add a placeholder.
*/
const char *dot = strchr(name, GUC_QUALIFIER_SEPARATOR);
if (dot != NULL &&
is_custom_class(name, dot - name, custom_variable_classes))
if (strchr(name, GUC_QUALIFIER_SEPARATOR) != NULL)
return add_placeholder_variable(name, elevel);
}
......@@ -7456,7 +7402,6 @@ write_nondefault_variables(GucContext context)
{
int elevel;
FILE *fp;
struct config_generic *cvc_conf;
int i;
Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
......@@ -7476,20 +7421,9 @@ write_nondefault_variables(GucContext context)
return;
}
/*
* custom_variable_classes must be written out first; otherwise we might
* reject custom variable values while reading the file.
*/
cvc_conf = find_option("custom_variable_classes", false, ERROR);
if (cvc_conf)
write_one_nondefault_variable(fp, cvc_conf);
for (i = 0; i < num_guc_variables; i++)
{
struct config_generic *gconf = guc_variables[i];
if (gconf != cvc_conf)
write_one_nondefault_variable(fp, gconf);
write_one_nondefault_variable(fp, guc_variables[i]);
}
if (FreeFile(fp))
......@@ -8142,64 +8076,6 @@ assign_phony_autocommit(bool newval, bool doit, GucSource source)
return true;
}
static const char *
assign_custom_variable_classes(const char *newval, bool doit, GucSource source)
{
/*
* Check syntax. newval must be a comma separated list of identifiers.
* Whitespace is allowed but removed from the result.
*/
bool hasSpaceAfterToken = false;
const char *cp = newval;
int symLen = 0;
char c;
StringInfoData buf;
initStringInfo(&buf);
while ((c = *cp++) != '\0')
{
if (isspace((unsigned char) c))
{
if (symLen > 0)
hasSpaceAfterToken = true;
continue;
}
if (c == ',')
{
if (symLen > 0) /* terminate identifier */
{
appendStringInfoChar(&buf, ',');
symLen = 0;
}
hasSpaceAfterToken = false;
continue;
}
if (hasSpaceAfterToken || !(isalnum((unsigned char) c) || c == '_'))
{
/*
* Syntax error due to token following space after token or
* non-identifier character
*/
pfree(buf.data);
return NULL;
}
appendStringInfoChar(&buf, c);
symLen++;
}
/* Remove stray ',' at end */
if (symLen == 0 && buf.len > 0)
buf.data[--buf.len] = '\0';
/* GUC wants the result malloc'd */
newval = guc_strdup(LOG, buf.data);
pfree(buf.data);
return newval;
}
static bool
assign_debug_assertions(bool newval, bool doit, GucSource source)
{
......
......@@ -550,4 +550,4 @@ gp_vmem_protect_limit = 8192 #Virtual memory limit (in MB).
# CUSTOMIZED OPTIONS
#------------------------------------------------------------------------------
#custom_variable_classes = '' # list of custom variable class names
# Add settings for extensions here
-- test plperl.on_plperl_init errors are fatal
-- Avoid need for custom_variable_classes = 'plperl'
-- Must load plperl before we can set on_plperl_init
LOAD 'plperl';
SET SESSION plperl.on_plperl_init = ' system("/nonesuch"); ';
SHOW plperl.on_plperl_init;
......
-- test plperl.on_plperl_init via the shared hash
-- (must be done before plperl is first used)
-- Avoid need for custom_variable_classes = 'plperl'
-- Must load plperl before we can set on_plperl_init
LOAD 'plperl';
-- testing on_plperl_init gets run, and that it can alter %_SHARED
SET plperl.on_plperl_init = '$_SHARED{on_init} = 42';
......
-- Use ONLY plperlu tests here. For plperl/plerlu combined tests
-- see plperl_plperlu.sql
-- Avoid need for custom_variable_classes = 'plperl'
-- Must load plperl before we can set on_plperlu_init
LOAD 'plperl';
-- Test plperl.on_plperlu_init gets run
SET plperl.on_plperlu_init = '$_SHARED{init} = 42';
......
-- test plperl.on_plperl_init errors are fatal
-- Avoid need for custom_variable_classes = 'plperl'
-- Must load plperl before we can set on_plperl_init
LOAD 'plperl';
SET SESSION plperl.on_plperl_init = ' system("/nonesuch"); ';
......
-- test plperl.on_plperl_init via the shared hash
-- (must be done before plperl is first used)
-- Avoid need for custom_variable_classes = 'plperl'
-- Must load plperl before we can set on_plperl_init
LOAD 'plperl';
-- testing on_plperl_init gets run, and that it can alter %_SHARED
......
-- Use ONLY plperlu tests here. For plperl/plerlu combined tests
-- see plperl_plperlu.sql
-- Avoid need for custom_variable_classes = 'plperl'
-- Must load plperl before we can set on_plperlu_init
LOAD 'plperl';
-- Test plperl.on_plperlu_init gets run
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册