Skip to content

Commit b7edb56

Browse files
committed
Make configuration parameters fall back to their default values when they
are removed from the configuration file. Joachim Wieland
1 parent adf7788 commit b7edb56

File tree

3 files changed

+258
-37
lines changed

3 files changed

+258
-37
lines changed

src/backend/utils/misc/guc-file.l

Lines changed: 149 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
66
*
7-
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.49 2007/03/13 14:32:25 petere Exp $
7+
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.50 2007/04/21 20:02:40 petere Exp $
88
*/
99

1010
%{
@@ -116,6 +116,9 @@ ProcessConfigFile(GucContext context)
116116
{
117117
int elevel;
118118
struct name_value_pair *item, *head, *tail;
119+
int i;
120+
bool *in_conffile = NULL;
121+
const char *var;
119122
120123
Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
121124
@@ -140,19 +143,158 @@ ProcessConfigFile(GucContext context)
140143
/* Check if all options are valid */
141144
for (item = head; item; item = item->next)
142145
{
146+
char *sep = strchr(item->name, GUC_QUALIFIER_SEPARATOR);
147+
if (sep && !is_custom_class(item->name, sep - item->name))
148+
{
149+
ereport(elevel,
150+
(errcode(ERRCODE_UNDEFINED_OBJECT),
151+
errmsg("unrecognized configuration parameter \"%s\"",
152+
item->name)));
153+
goto cleanup_list;
154+
}
155+
143156
if (!set_config_option(item->name, item->value, context,
144157
PGC_S_FILE, false, false))
145158
goto cleanup_list;
146159
}
147160
148-
/* If we got here all the options checked out okay, so apply them. */
161+
162+
/*
163+
* Mark all variables as not showing up in the config file. The
164+
* allocation has to take place after ParseConfigFile() since this
165+
* function can change num_guc_variables due to custom variables.
166+
* It would be easier to add a new field or status bit to struct
167+
* conf_generic, but that way we would expose internal information
168+
* that is just needed here in the following few lines. The price
169+
* to pay for this separation are a few more loops over the set of
170+
* configuration options, but those are expected to be rather few
171+
* and we only have to pay the cost at SIGHUP. We initialize
172+
* in_conffile only here because set_config_option() makes
173+
* guc_variables grow with custom variables.
174+
*/
175+
in_conffile = guc_malloc(elevel, num_guc_variables * sizeof(bool));
176+
if (!in_conffile)
177+
goto cleanup_list;
178+
for (i = 0; i < num_guc_variables; i++)
179+
in_conffile[i] = false;
180+
149181
for (item = head; item; item = item->next)
150182
{
183+
/*
184+
* After set_config_option() the variable name item->name is
185+
* known to exist.
186+
*/
187+
Assert(guc_get_index(item->name) >= 0);
188+
in_conffile[guc_get_index(item->name)] = true;
189+
}
190+
191+
for (i = 0; i < num_guc_variables; i++)
192+
{
193+
struct config_generic *gconf = guc_variables[i];
194+
if (!in_conffile[i] && gconf->source == PGC_S_FILE)
195+
{
196+
if (gconf->context < PGC_SIGHUP)
197+
ereport(elevel,
198+
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
199+
errmsg("parameter \"%s\" cannot be changed after server start; configuration file change ignored",
200+
gconf->name)));
201+
else
202+
{
203+
/* prepare */
204+
GucStack *stack;
205+
if (gconf->reset_source == PGC_S_FILE)
206+
gconf->reset_source = PGC_S_DEFAULT;
207+
for (stack = gconf->stack; stack; stack = stack->prev)
208+
if (stack->source == PGC_S_FILE)
209+
stack->source = PGC_S_DEFAULT;
210+
/* apply the default */
211+
set_config_option(gconf->name, NULL, context,
212+
PGC_S_DEFAULT, false, true);
213+
}
214+
}
215+
else if (!in_conffile[i] && gconf->reset_source == PGC_S_FILE)
216+
{
217+
/*------
218+
* Change the reset_val to default_val. Here's an
219+
* example: In the configuration file we have
220+
*
221+
* seq_page_cost = 3.00
222+
*
223+
* Now we execute in a session
224+
*
225+
* SET seq_page_cost TO 4.00;
226+
*
227+
* Then we remove this option from the configuration file
228+
* and send SIGHUP. Now when you execute
229+
*
230+
* RESET seq_page_cost;
231+
*
232+
* it should fall back to 1.00 (the default value for
233+
* seq_page_cost) and not to 3.00 (which is the current
234+
* reset_val).
235+
*/
236+
237+
switch (gconf->vartype)
238+
{
239+
case PGC_BOOL:
240+
{
241+
struct config_bool *conf;
242+
conf = (struct config_bool *) gconf;
243+
conf->reset_val = conf->boot_val;
244+
break;
245+
}
246+
case PGC_INT:
247+
{
248+
struct config_int *conf;
249+
conf = (struct config_int *) gconf;
250+
conf->reset_val = conf->boot_val;
251+
break;
252+
}
253+
case PGC_REAL:
254+
{
255+
struct config_real *conf;
256+
conf = (struct config_real *) gconf;
257+
conf->reset_val = conf->boot_val;
258+
break;
259+
}
260+
case PGC_STRING:
261+
{
262+
struct config_string *conf;
263+
conf = (struct config_string *) gconf;
264+
/*
265+
* We can cast away the const here because we
266+
* won't free the address. It is protected by
267+
* set_string_field() and string_field_used().
268+
*/
269+
conf->reset_val = (char *) conf->boot_val;
270+
break;
271+
}
272+
}
273+
}
274+
}
275+
276+
/* If we got here all the options checked out okay, so apply them. */
277+
for (item = head; item; item = item->next)
151278
set_config_option(item->name, item->value, context,
152279
PGC_S_FILE, false, true);
153-
}
280+
281+
/*
282+
* Reset variables to the value of environment variables
283+
* (PGC_S_ENV_VAR overrules PGC_S_FILE). PGPORT is ignored,
284+
* because it cannot be changed without restart.
285+
*/
286+
var = getenv("PGDATESTYLE");
287+
if (var != NULL)
288+
set_config_option("datestyle", var, context,
289+
PGC_S_ENV_VAR, false, true);
290+
291+
var = getenv("PGCLIENTENCODING");
292+
if (var != NULL)
293+
set_config_option("client_encoding", var, context,
294+
PGC_S_ENV_VAR, false, true);
154295

155296
cleanup_list:
297+
free(in_conffile);
156298
free_name_value_list(head);
157299
}
158300

@@ -312,14 +454,14 @@ ParseConfigFile(const char *config_file, const char *calling_file,
312454
{
313455
pfree(opt_name);
314456
pfree(opt_value);
315-
/* we assume error message was logged already */
457+
458+
/* We assume the error message was logged already. */
316459
OK = false;
317460
goto cleanup_exit;
318461
}
319-
pfree(opt_name);
320-
pfree(opt_value);
321462
}
322-
else
463+
464+
if (pg_strcasecmp(opt_name, "include") != 0)
323465
{
324466
/* append to list */
325467
struct name_value_pair *item;

0 commit comments

Comments
 (0)