3 * Scanner for the configuration file
5 * Copyright (c) 2000-2010, PostgreSQL Global Development Group
7 * src/backend/utils/misc/guc-file.l
17 #include "miscadmin.h"
18 #include "storage/fd.h"
19 #include "utils/guc.h"
22 /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
24 #define fprintf(file, fmt, msg) ereport(ERROR, (errmsg_internal("%s", msg)))
32 GUC_UNQUOTED_STRING = 6,
38 struct name_value_pair
44 struct name_value_pair *next;
47 static unsigned int ConfigFileLineno;
49 /* flex fails to supply a prototype for yylex, so provide one */
52 static bool ParseConfigFile(const char *config_file, const char *calling_file,
53 int depth, int elevel,
54 struct name_value_pair **head_p,
55 struct name_value_pair **tail_p);
56 static void free_name_value_list(struct name_value_pair * list);
57 static char *GUC_scanstr(const char *s);
62 %option never-interactive
67 %option prefix="GUC_yy"
76 INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+){UNIT_LETTER}*
78 EXPONENT [Ee]{SIGN}?{DIGIT}+
79 REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}?
81 LETTER [A-Za-z_\200-\377]
82 LETTER_OR_DIGIT [A-Za-z_0-9\200-\377]
84 ID {LETTER}{LETTER_OR_DIGIT}*
85 QUALIFIED_ID {ID}"."{ID}
87 UNQUOTED_STRING {LETTER}({LETTER_OR_DIGIT}|[-._:/])*
88 STRING \'([^'\\\n]|\\.|\'\')*\'
92 \n ConfigFileLineno++; return GUC_EOL;
93 [ \t\r]+ /* eat whitespace */
94 #.* /* eat comment (.* matches anything until newline) */
97 {QUALIFIED_ID} return GUC_QUALIFIED_ID;
98 {STRING} return GUC_STRING;
99 {UNQUOTED_STRING} return GUC_UNQUOTED_STRING;
100 {INTEGER} return GUC_INTEGER;
101 {REAL} return GUC_REAL;
111 * Exported function to read and process the configuration file. The
112 * parameter indicates in what context the file is being read --- either
113 * postmaster startup (including standalone-backend startup) or SIGHUP.
114 * All options mentioned in the configuration file are set to new values.
115 * If an error occurs, no values will be changed.
118 ProcessConfigFile(GucContext context)
121 struct name_value_pair *item, *head, *tail;
123 struct config_string *cvc_struct;
127 Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
129 if (context == PGC_SIGHUP)
132 * To avoid cluttering the log, only the postmaster bleats loudly
133 * about problems with the config file.
135 elevel = IsUnderPostmaster ? DEBUG2 : LOG;
140 /* Parse the file into a list of option names and values */
143 if (!ParseConfigFile(ConfigFileName, NULL, 0, elevel, &head, &tail))
147 * We need the proposed new value of custom_variable_classes to check
148 * custom variables with. ParseConfigFile ensured that if it's in
149 * the file, it's first in the list. But first check to see if we
150 * have an active value from the command line, which should override
151 * the file in any case. (Since there's no relevant env var, the
152 * only possible nondefault sources are the file and ARGV.)
154 cvc_struct = (struct config_string *)
155 find_option("custom_variable_classes", false, elevel);
156 if (cvc_struct && cvc_struct->gen.reset_source > PGC_S_FILE)
158 cvc = guc_strdup(elevel, cvc_struct->reset_val);
162 else if (head != NULL &&
163 guc_name_compare(head->name, "custom_variable_classes") == 0)
166 * Need to canonicalize the value via the assign hook. Casting away
167 * const is a bit ugly, but we know the result is malloc'd.
169 cvc = (char *) assign_custom_variable_classes(head->value,
174 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
175 errmsg("invalid value for parameter \"%s\": \"%s\"",
176 head->name, head->value)));
182 * Mark all extant GUC variables as not present in the config file.
183 * We need this so that we can tell below which ones have been removed
184 * from the file since we last processed it.
186 for (i = 0; i < num_guc_variables; i++)
188 struct config_generic *gconf = guc_variables[i];
190 gconf->status &= ~GUC_IS_IN_FILE;
194 * Check if all options are valid. As a side-effect, the GUC_IS_IN_FILE
195 * flag is set on each GUC variable mentioned in the list.
197 for (item = head; item; item = item->next)
199 char *sep = strchr(item->name, GUC_QUALIFIER_SEPARATOR);
204 * We have to consider three cases for custom variables:
206 * 1. The class name is not valid according to the (new) setting
207 * of custom_variable_classes. If so, reject. We don't care
208 * which side is at fault.
210 if (!is_custom_class(item->name, sep - item->name, cvc))
213 (errcode(ERRCODE_UNDEFINED_OBJECT),
214 errmsg("unrecognized configuration parameter \"%s\"",
219 * 2. There is no GUC entry. If we called set_config_option then
220 * it would make a placeholder, which we don't want to do yet,
221 * since we could still fail further down the list. Do nothing
222 * (assuming that making the placeholder will succeed later).
224 if (find_option(item->name, false, elevel) == NULL)
227 * 3. There is already a GUC entry (either real or placeholder) for
228 * the variable. In this case we should let set_config_option
229 * check it, since the assignment could well fail if it's a real
234 if (!set_config_option(item->name, item->value, context,
235 PGC_S_FILE, GUC_ACTION_SET, false))
240 * Check for variables having been removed from the config file, and
241 * revert their reset values (and perhaps also effective values) to the
242 * boot-time defaults. If such a variable can't be changed after startup,
243 * just throw a warning and continue. (This is analogous to the fact that
244 * set_config_option only throws a warning for a new but different value.
245 * If we wanted to make it a hard error, we'd need an extra pass over the
246 * list so that we could throw the error before starting to apply
249 for (i = 0; i < num_guc_variables; i++)
251 struct config_generic *gconf = guc_variables[i];
254 if (gconf->reset_source != PGC_S_FILE ||
255 (gconf->status & GUC_IS_IN_FILE))
257 if (gconf->context < PGC_SIGHUP)
260 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
261 errmsg("parameter \"%s\" cannot be changed without restarting the server",
267 * Reset any "file" sources to "default", else set_config_option
268 * will not override those settings.
270 if (gconf->reset_source == PGC_S_FILE)
271 gconf->reset_source = PGC_S_DEFAULT;
272 if (gconf->source == PGC_S_FILE)
273 gconf->source = PGC_S_DEFAULT;
274 for (stack = gconf->stack; stack; stack = stack->prev)
276 if (stack->source == PGC_S_FILE)
277 stack->source = PGC_S_DEFAULT;
280 /* Now we can re-apply the wired-in default */
281 set_config_option(gconf->name, NULL, context, PGC_S_DEFAULT,
282 GUC_ACTION_SET, true);
283 if (context == PGC_SIGHUP)
285 (errmsg("parameter \"%s\" removed from configuration file, reset to default",
290 * Restore any variables determined by environment variables. This
291 * is a no-op except in the case where one of these had been in the
292 * config file and is now removed. PGC_S_ENV_VAR will override the
293 * wired-in default we just applied, but cannot override any other source.
295 * Keep this list in sync with InitializeGUCOptions()!
296 * PGPORT can be ignored, because it cannot be changed without restart.
297 * We assume rlimit hasn't changed, either.
299 envvar = getenv("PGDATESTYLE");
301 set_config_option("datestyle", envvar, PGC_POSTMASTER,
302 PGC_S_ENV_VAR, GUC_ACTION_SET, true);
304 envvar = getenv("PGCLIENTENCODING");
306 set_config_option("client_encoding", envvar, PGC_POSTMASTER,
307 PGC_S_ENV_VAR, GUC_ACTION_SET, true);
310 /* If we got here all the options checked out okay, so apply them. */
311 for (item = head; item; item = item->next)
313 char *pre_value = NULL;
315 /* In SIGHUP cases in the postmaster, report changes */
316 if (context == PGC_SIGHUP && !IsUnderPostmaster)
318 const char *preval = GetConfigOption(item->name, false);
320 /* string variables could be NULL; treat that as empty */
323 /* must dup, else might have dangling pointer below */
324 pre_value = pstrdup(preval);
327 if (set_config_option(item->name, item->value, context,
328 PGC_S_FILE, GUC_ACTION_SET, true))
330 set_config_sourcefile(item->name, item->filename,
335 const char *post_value = GetConfigOption(item->name, false);
339 if (strcmp(pre_value, post_value) != 0)
341 (errmsg("parameter \"%s\" changed to \"%s\"",
342 item->name, item->value)));
350 /* Remember when we last successfully loaded the config file. */
351 PgReloadTime = GetCurrentTimestamp();
354 free_name_value_list(head);
361 * Read and parse a single configuration file. This function recurses
362 * to handle "include" directives.
365 * config_file: absolute or relative path of file to read
366 * calling_file: absolute path of file containing the "include" directive,
367 * or NULL at outer level (config_file must be absolute at outer level)
368 * depth: recursion depth (used only to prevent infinite recursion)
369 * elevel: error logging level determined by ProcessConfigFile()
371 * head_p, tail_p: head and tail of linked list of name/value pairs
373 * *head_p and *tail_p must be initialized to NULL before calling the outer
374 * recursion level. On exit, they contain a list of name-value pairs read
375 * from the input file(s).
377 * Returns TRUE if successful, FALSE if an error occurred. The error has
378 * already been ereport'd, it is only necessary for the caller to clean up
379 * its own state and release the name/value pairs list.
381 * Note: if elevel >= ERROR then an error will not return control to the
382 * caller, and internal state such as open files will not be cleaned up.
383 * This case occurs only during postmaster or standalone-backend startup,
384 * where an error will lead to immediate process exit anyway; so there is
385 * no point in contorting the code so it can clean up nicely.
388 ParseConfigFile(const char *config_file, const char *calling_file,
389 int depth, int elevel,
390 struct name_value_pair **head_p,
391 struct name_value_pair **tail_p)
394 char abs_path[MAXPGPATH];
396 YY_BUFFER_STATE lex_buffer;
400 * Reject too-deep include nesting depth. This is just a safety check
401 * to avoid dumping core due to stack overflow if an include file loops
402 * back to itself. The maximum nesting depth is pretty arbitrary.
407 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
408 errmsg("could not open configuration file \"%s\": maximum nesting depth exceeded",
414 * If config_file is a relative path, convert to absolute. We consider
415 * it to be relative to the directory holding the calling file.
417 if (!is_absolute_path(config_file))
419 Assert(calling_file != NULL);
420 strlcpy(abs_path, calling_file, sizeof(abs_path));
421 get_parent_directory(abs_path);
422 join_path_components(abs_path, abs_path, config_file);
423 canonicalize_path(abs_path);
424 config_file = abs_path;
427 fp = AllocateFile(config_file, "r");
431 (errcode_for_file_access(),
432 errmsg("could not open configuration file \"%s\": %m",
440 lex_buffer = yy_create_buffer(fp, YY_BUF_SIZE);
441 yy_switch_to_buffer(lex_buffer);
443 ConfigFileLineno = 1;
445 /* This loop iterates once per logical line */
446 while ((token = yylex()))
448 char *opt_name, *opt_value;
449 struct name_value_pair *item;
451 if (token == GUC_EOL) /* empty or comment line */
454 /* first token on line is option name */
455 if (token != GUC_ID && token != GUC_QUALIFIED_ID)
457 opt_name = pstrdup(yytext);
459 /* next we have an optional equal sign; discard if present */
461 if (token == GUC_EQUALS)
464 /* now we must have the option value */
465 if (token != GUC_ID &&
466 token != GUC_STRING &&
467 token != GUC_INTEGER &&
469 token != GUC_UNQUOTED_STRING)
471 if (token == GUC_STRING) /* strip quotes and escapes */
472 opt_value = GUC_scanstr(yytext);
474 opt_value = pstrdup(yytext);
476 /* now we'd like an end of line, or possibly EOF */
478 if (token != GUC_EOL)
482 /* treat EOF like \n for line numbering purposes, cf bug 4752 */
486 /* OK, process the option name and value */
487 if (guc_name_compare(opt_name, "include") == 0)
490 * An include directive isn't a variable and should be processed
493 unsigned int save_ConfigFileLineno = ConfigFileLineno;
495 if (!ParseConfigFile(opt_value, config_file,
504 yy_switch_to_buffer(lex_buffer);
505 ConfigFileLineno = save_ConfigFileLineno;
509 else if (guc_name_compare(opt_name, "custom_variable_classes") == 0)
512 * This variable must be processed first as it controls
513 * the validity of other variables; so it goes at the head
514 * of the result list. If we already found a value for it,
515 * replace with this one.
519 guc_name_compare(item->name, "custom_variable_classes") == 0)
521 /* replace existing head item */
524 item->name = opt_name;
525 item->value = opt_value;
526 item->filename = pstrdup(config_file);
527 item->sourceline = ConfigFileLineno-1;
531 /* prepend to list */
532 item = palloc(sizeof *item);
533 item->name = opt_name;
534 item->value = opt_value;
535 item->filename = pstrdup(config_file);
536 item->sourceline = ConfigFileLineno-1;
537 item->next = *head_p;
545 /* ordinary variable, append to list */
546 item = palloc(sizeof *item);
547 item->name = opt_name;
548 item->value = opt_value;
549 item->filename = pstrdup(config_file);
550 item->sourceline = ConfigFileLineno-1;
555 (*tail_p)->next = item;
559 /* break out of loop if read EOF, else loop for next line */
564 /* successful completion of parsing */
568 if (token == GUC_EOL || token == 0)
570 (errcode(ERRCODE_SYNTAX_ERROR),
571 errmsg("syntax error in file \"%s\" line %u, near end of line",
572 config_file, ConfigFileLineno - 1)));
575 (errcode(ERRCODE_SYNTAX_ERROR),
576 errmsg("syntax error in file \"%s\" line %u, near token \"%s\"",
577 config_file, ConfigFileLineno, yytext)));
581 yy_delete_buffer(lex_buffer);
588 * Free a list of name/value pairs, including the names and the values
591 free_name_value_list(struct name_value_pair *list)
593 struct name_value_pair *item;
598 struct name_value_pair *next = item->next;
602 pfree(item->filename);
612 * Strip the quotes surrounding the given string, and collapse any embedded
613 * '' sequences and backslash escapes.
615 * the string returned is palloc'd and should eventually be pfree'd by the
619 GUC_scanstr(const char *s)
626 Assert(s != NULL && s[0] == '\'');
629 Assert(s[len-1] == '\'');
631 /* Skip the leading quote; we'll handle the trailing quote below */
634 /* Since len still includes trailing quote, this is enough space */
635 newStr = palloc(len);
637 for (i = 0, j = 0; i < len; i++)
672 s[i + k] >= '0' && s[i + k] <= '7' && k < 3;
674 octVal = (octVal << 3) + (s[i + k] - '0');
676 newStr[j] = ((char) octVal);
684 else if (s[i] == '\'' && s[i+1] == '\'')
686 /* doubled quote becomes just one quote */
694 /* We copied the ending quote to newStr, so replace with \0 */
695 Assert(j > 0 && j <= len);