PostgreSQL Source Code git master
guc_internal.h File Reference
#include "utils/guc.h"
Include dependency graph for guc_internal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int guc_name_compare (const char *namea, const char *nameb)
 
ConfigVariableProcessConfigFileInternal (GucContext context, bool applySettings, int elevel)
 
void record_config_file_error (const char *errmsg, const char *config_file, int lineno, ConfigVariable **head_p, ConfigVariable **tail_p)
 

Function Documentation

◆ guc_name_compare()

int guc_name_compare ( const char *  namea,
const char *  nameb 
)

Definition at line 1300 of file guc.c.

1301{
1302 /*
1303 * The temptation to use strcasecmp() here must be resisted, because the
1304 * hash mapping has to remain stable across setlocale() calls. So, build
1305 * our own with a simple ASCII-only downcasing.
1306 */
1307 while (*namea && *nameb)
1308 {
1309 char cha = *namea++;
1310 char chb = *nameb++;
1311
1312 if (cha >= 'A' && cha <= 'Z')
1313 cha += 'a' - 'A';
1314 if (chb >= 'A' && chb <= 'Z')
1315 chb += 'a' - 'A';
1316 if (cha != chb)
1317 return cha - chb;
1318 }
1319 if (*namea)
1320 return 1; /* a is longer */
1321 if (*nameb)
1322 return -1; /* b is longer */
1323 return 0;
1324}

Referenced by convert_GUC_name_for_parameter_acl(), find_option(), GetPGVariable(), GetPGVariableResultDesc(), guc_name_match(), guc_var_compare(), ParseConfigFp(), and replace_auto_config_value().

◆ ProcessConfigFileInternal()

ConfigVariable * ProcessConfigFileInternal ( GucContext  context,
bool  applySettings,
int  elevel 
)

Definition at line 282 of file guc.c.

283{
284 bool error = false;
285 bool applying = false;
286 const char *ConfFileWithError;
287 ConfigVariable *item,
288 *head,
289 *tail;
290 HASH_SEQ_STATUS status;
291 GUCHashEntry *hentry;
292
293 /* Parse the main config file into a list of option names and values */
294 ConfFileWithError = ConfigFileName;
295 head = tail = NULL;
296
298 NULL, 0, CONF_FILE_START_DEPTH, elevel,
299 &head, &tail))
300 {
301 /* Syntax error(s) detected in the file, so bail out */
302 error = true;
303 goto bail_out;
304 }
305
306 /*
307 * Parse the PG_AUTOCONF_FILENAME file, if present, after the main file to
308 * replace any parameters set by ALTER SYSTEM command. Because this file
309 * is in the data directory, we can't read it until the DataDir has been
310 * set.
311 */
312 if (DataDir)
313 {
315 NULL, 0, CONF_FILE_START_DEPTH, elevel,
316 &head, &tail))
317 {
318 /* Syntax error(s) detected in the file, so bail out */
319 error = true;
320 ConfFileWithError = PG_AUTOCONF_FILENAME;
321 goto bail_out;
322 }
323 }
324 else
325 {
326 /*
327 * If DataDir is not set, the PG_AUTOCONF_FILENAME file cannot be
328 * read. In this case, we don't want to accept any settings but
329 * data_directory from postgresql.conf, because they might be
330 * overwritten with settings in the PG_AUTOCONF_FILENAME file which
331 * will be read later. OTOH, since data_directory isn't allowed in the
332 * PG_AUTOCONF_FILENAME file, it will never be overwritten later.
333 */
334 ConfigVariable *newlist = NULL;
335
336 /*
337 * Prune all items except the last "data_directory" from the list.
338 */
339 for (item = head; item; item = item->next)
340 {
341 if (!item->ignore &&
342 strcmp(item->name, "data_directory") == 0)
343 newlist = item;
344 }
345
346 if (newlist)
347 newlist->next = NULL;
348 head = tail = newlist;
349
350 /*
351 * Quick exit if data_directory is not present in file.
352 *
353 * We need not do any further processing, in particular we don't set
354 * PgReloadTime; that will be set soon by subsequent full loading of
355 * the config file.
356 */
357 if (head == NULL)
358 goto bail_out;
359 }
360
361 /*
362 * Mark all extant GUC variables as not present in the config file. We
363 * need this so that we can tell below which ones have been removed from
364 * the file since we last processed it.
365 */
366 hash_seq_init(&status, guc_hashtab);
367 while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
368 {
369 struct config_generic *gconf = hentry->gucvar;
370
371 gconf->status &= ~GUC_IS_IN_FILE;
372 }
373
374 /*
375 * Check if all the supplied option names are valid, as an additional
376 * quasi-syntactic check on the validity of the config file. It is
377 * important that the postmaster and all backends agree on the results of
378 * this phase, else we will have strange inconsistencies about which
379 * processes accept a config file update and which don't. Hence, unknown
380 * custom variable names have to be accepted without complaint. For the
381 * same reason, we don't attempt to validate the options' values here.
382 *
383 * In addition, the GUC_IS_IN_FILE flag is set on each existing GUC
384 * variable mentioned in the file; and we detect duplicate entries in the
385 * file and mark the earlier occurrences as ignorable.
386 */
387 for (item = head; item; item = item->next)
388 {
389 struct config_generic *record;
390
391 /* Ignore anything already marked as ignorable */
392 if (item->ignore)
393 continue;
394
395 /*
396 * Try to find the variable; but do not create a custom placeholder if
397 * it's not there already.
398 */
399 record = find_option(item->name, false, true, elevel);
400
401 if (record)
402 {
403 /* If it's already marked, then this is a duplicate entry */
404 if (record->status & GUC_IS_IN_FILE)
405 {
406 /*
407 * Mark the earlier occurrence(s) as dead/ignorable. We could
408 * avoid the O(N^2) behavior here with some additional state,
409 * but it seems unlikely to be worth the trouble.
410 */
411 ConfigVariable *pitem;
412
413 for (pitem = head; pitem != item; pitem = pitem->next)
414 {
415 if (!pitem->ignore &&
416 strcmp(pitem->name, item->name) == 0)
417 pitem->ignore = true;
418 }
419 }
420 /* Now mark it as present in file */
421 record->status |= GUC_IS_IN_FILE;
422 }
423 else if (!valid_custom_variable_name(item->name))
424 {
425 /* Invalid non-custom variable, so complain */
426 ereport(elevel,
427 (errcode(ERRCODE_UNDEFINED_OBJECT),
428 errmsg("unrecognized configuration parameter \"%s\" in file \"%s\" line %d",
429 item->name,
430 item->filename, item->sourceline)));
431 item->errmsg = pstrdup("unrecognized configuration parameter");
432 error = true;
433 ConfFileWithError = item->filename;
434 }
435 }
436
437 /*
438 * If we've detected any errors so far, we don't want to risk applying any
439 * changes.
440 */
441 if (error)
442 goto bail_out;
443
444 /* Otherwise, set flag that we're beginning to apply changes */
445 applying = true;
446
447 /*
448 * Check for variables having been removed from the config file, and
449 * revert their reset values (and perhaps also effective values) to the
450 * boot-time defaults. If such a variable can't be changed after startup,
451 * report that and continue.
452 */
454 while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
455 {
456 struct config_generic *gconf = hentry->gucvar;
458
459 if (gconf->reset_source != PGC_S_FILE ||
460 (gconf->status & GUC_IS_IN_FILE))
461 continue;
462 if (gconf->context < PGC_SIGHUP)
463 {
464 /* The removal can't be effective without a restart */
465 gconf->status |= GUC_PENDING_RESTART;
466 ereport(elevel,
467 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
468 errmsg("parameter \"%s\" cannot be changed without restarting the server",
469 gconf->name)));
470 record_config_file_error(psprintf("parameter \"%s\" cannot be changed without restarting the server",
471 gconf->name),
472 NULL, 0,
473 &head, &tail);
474 error = true;
475 continue;
476 }
477
478 /* No more to do if we're just doing show_all_file_settings() */
479 if (!applySettings)
480 continue;
481
482 /*
483 * Reset any "file" sources to "default", else set_config_option will
484 * not override those settings.
485 */
486 if (gconf->reset_source == PGC_S_FILE)
488 if (gconf->source == PGC_S_FILE)
490 for (stack = gconf->stack; stack; stack = stack->prev)
491 {
492 if (stack->source == PGC_S_FILE)
494 }
495
496 /* Now we can re-apply the wired-in default (i.e., the boot_val) */
497 if (set_config_option(gconf->name, NULL,
499 GUC_ACTION_SET, true, 0, false) > 0)
500 {
501 /* Log the change if appropriate */
502 if (context == PGC_SIGHUP)
503 ereport(elevel,
504 (errmsg("parameter \"%s\" removed from configuration file, reset to default",
505 gconf->name)));
506 }
507 }
508
509 /*
510 * Restore any variables determined by environment variables or
511 * dynamically-computed defaults. This is a no-op except in the case
512 * where one of these had been in the config file and is now removed.
513 *
514 * In particular, we *must not* do this during the postmaster's initial
515 * loading of the file, since the timezone functions in particular should
516 * be run only after initialization is complete.
517 *
518 * XXX this is an unmaintainable crock, because we have to know how to set
519 * (or at least what to call to set) every non-PGC_INTERNAL variable that
520 * could potentially have PGC_S_DYNAMIC_DEFAULT or PGC_S_ENV_VAR source.
521 */
522 if (context == PGC_SIGHUP && applySettings)
523 {
526 /* this selects SQL_ASCII in processes not connected to a database */
527 SetConfigOption("client_encoding", GetDatabaseEncodingName(),
529 }
530
531 /*
532 * Now apply the values from the config file.
533 */
534 for (item = head; item; item = item->next)
535 {
536 char *pre_value = NULL;
537 int scres;
538
539 /* Ignore anything marked as ignorable */
540 if (item->ignore)
541 continue;
542
543 /* In SIGHUP cases in the postmaster, we want to report changes */
544 if (context == PGC_SIGHUP && applySettings && !IsUnderPostmaster)
545 {
546 const char *preval = GetConfigOption(item->name, true, false);
547
548 /* If option doesn't exist yet or is NULL, treat as empty string */
549 if (!preval)
550 preval = "";
551 /* must dup, else might have dangling pointer below */
552 pre_value = pstrdup(preval);
553 }
554
555 scres = set_config_option(item->name, item->value,
557 GUC_ACTION_SET, applySettings, 0, false);
558 if (scres > 0)
559 {
560 /* variable was updated, so log the change if appropriate */
561 if (pre_value)
562 {
563 const char *post_value = GetConfigOption(item->name, true, false);
564
565 if (!post_value)
566 post_value = "";
567 if (strcmp(pre_value, post_value) != 0)
568 ereport(elevel,
569 (errmsg("parameter \"%s\" changed to \"%s\"",
570 item->name, item->value)));
571 }
572 item->applied = true;
573 }
574 else if (scres == 0)
575 {
576 error = true;
577 item->errmsg = pstrdup("setting could not be applied");
578 ConfFileWithError = item->filename;
579 }
580 else
581 {
582 /* no error, but variable's active value was not changed */
583 item->applied = true;
584 }
585
586 /*
587 * We should update source location unless there was an error, since
588 * even if the active value didn't change, the reset value might have.
589 * (In the postmaster, there won't be a difference, but it does matter
590 * in backends.)
591 */
592 if (scres != 0 && applySettings)
594 item->sourceline);
595
596 if (pre_value)
597 pfree(pre_value);
598 }
599
600 /* Remember when we last successfully loaded the config file. */
601 if (applySettings)
603
605 if (error && applySettings)
606 {
607 /* During postmaster startup, any error is fatal */
608 if (context == PGC_POSTMASTER)
610 (errcode(ERRCODE_CONFIG_FILE_ERROR),
611 errmsg("configuration file \"%s\" contains errors",
612 ConfFileWithError)));
613 else if (applying)
614 ereport(elevel,
615 (errcode(ERRCODE_CONFIG_FILE_ERROR),
616 errmsg("configuration file \"%s\" contains errors; unaffected changes were applied",
617 ConfFileWithError)));
618 else
619 ereport(elevel,
620 (errcode(ERRCODE_CONFIG_FILE_ERROR),
621 errmsg("configuration file \"%s\" contains errors; no changes were applied",
622 ConfFileWithError)));
623 }
624
625 /* Successful or otherwise, return the collected data list */
626 return head;
627}
TimestampTz PgReloadTime
Definition: timestamp.c:56
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1644
#define CONF_FILE_START_DEPTH
Definition: conffiles.h:17
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1420
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1385
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
bool IsUnderPostmaster
Definition: globals.c:119
char * DataDir
Definition: globals.c:70
void record_config_file_error(const char *errmsg, const char *config_file, int lineno, ConfigVariable **head_p, ConfigVariable **tail_p)
Definition: guc-file.l:278
bool ParseConfigFile(const char *config_file, bool strict, const char *calling_file, int calling_lineno, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p)
Definition: guc-file.l:175
static void set_config_sourcefile(const char *name, char *sourcefile, int sourceline)
Definition: guc.c:4299
static bool valid_custom_variable_name(const char *name)
Definition: guc.c:1076
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:4332
const char * GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
Definition: guc.c:4355
static void pg_timezone_abbrev_initialize(void)
Definition: guc.c:1992
struct config_generic * find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel)
Definition: guc.c:1235
static void InitializeGUCOptionsFromEnvironment(void)
Definition: guc.c:1589
static void set_guc_source(struct config_generic *gconf, GucSource newsource)
Definition: guc.c:2111
static HTAB * guc_hashtab
Definition: guc.c:212
int set_config_option(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel, bool is_reload)
Definition: guc.c:3342
#define PG_AUTOCONF_FILENAME
Definition: guc.h:37
@ GUC_ACTION_SET
Definition: guc.h:203
@ PGC_S_DEFAULT
Definition: guc.h:113
@ PGC_S_DYNAMIC_DEFAULT
Definition: guc.h:114
@ PGC_S_FILE
Definition: guc.h:116
@ PGC_POSTMASTER
Definition: guc.h:74
@ PGC_SIGHUP
Definition: guc.h:75
@ PGC_BACKEND
Definition: guc.h:77
char * ConfigFileName
Definition: guc_tables.c:538
#define GUC_IS_IN_FILE
Definition: guc_tables.h:189
#define GUC_PENDING_RESTART
Definition: guc_tables.h:194
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1267
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void pfree(void *pointer)
Definition: mcxt.c:1521
static void bail_out(bool noatexit, const char *fmt,...) pg_attribute_printf(2
Definition: pg_regress.c:255
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
static void error(void)
Definition: sql-dyntest.c:147
char * name
Definition: guc.h:141
bool ignore
Definition: guc.h:146
struct ConfigVariable * next
Definition: guc.h:148
bool applied
Definition: guc.h:147
char * filename
Definition: guc.h:144
int sourceline
Definition: guc.h:145
char * value
Definition: guc.h:142
char * errmsg
Definition: guc.h:143
struct config_generic * gucvar
Definition: guc.c:209
GucContext context
Definition: guc_tables.h:159
const char * name
Definition: guc_tables.h:158
GucStack * stack
Definition: guc_tables.h:173
GucSource source
Definition: guc_tables.h:167
GucSource reset_source
Definition: guc_tables.h:168
struct guc_stack * prev
Definition: guc_tables.h:121
GucSource source
Definition: guc_tables.h:124

References ConfigVariable::applied, bail_out(), CONF_FILE_START_DEPTH, ConfigFileName, config_generic::context, DataDir, ereport, errcode(), errmsg(), ConfigVariable::errmsg, ERROR, error(), ConfigVariable::filename, find_option(), GetConfigOption(), GetCurrentTimestamp(), GetDatabaseEncodingName(), GUC_ACTION_SET, guc_hashtab, GUC_IS_IN_FILE, GUC_PENDING_RESTART, GUCHashEntry::gucvar, hash_seq_init(), hash_seq_search(), ConfigVariable::ignore, InitializeGUCOptionsFromEnvironment(), IsUnderPostmaster, ConfigVariable::name, config_generic::name, ConfigVariable::next, ParseConfigFile(), pfree(), PG_AUTOCONF_FILENAME, pg_timezone_abbrev_initialize(), PGC_BACKEND, PGC_POSTMASTER, PGC_S_DEFAULT, PGC_S_DYNAMIC_DEFAULT, PGC_S_FILE, PGC_SIGHUP, PgReloadTime, guc_stack::prev, psprintf(), pstrdup(), record_config_file_error(), config_generic::reset_source, set_config_option(), set_config_sourcefile(), set_guc_source(), SetConfigOption(), guc_stack::source, config_generic::source, ConfigVariable::sourceline, config_generic::stack, config_generic::status, valid_custom_variable_name(), and ConfigVariable::value.

Referenced by ProcessConfigFile(), and show_all_file_settings().

◆ record_config_file_error()

void record_config_file_error ( const char *  errmsg,
const char *  config_file,
int  lineno,
ConfigVariable **  head_p,
ConfigVariable **  tail_p 
)

Definition at line 278 of file guc-file.l.

283{
284 ConfigVariable *item;
285
286 item = palloc(sizeof *item);
287 item->name = NULL;
288 item->value = NULL;
289 item->errmsg = pstrdup(errmsg);
290 item->filename = config_file ? pstrdup(config_file) : NULL;
291 item->sourceline = lineno;
292 item->ignore = true;
293 item->applied = false;
294 item->next = NULL;
295 if (*head_p == NULL)
296 *head_p = item;
297 else
298 (*tail_p)->next = item;
299 *tail_p = item;
300}
void * palloc(Size size)
Definition: mcxt.c:1317
static char * config_file
Definition: pg_rewind.c:71

References ConfigVariable::applied, config_file, errmsg(), ConfigVariable::errmsg, ConfigVariable::filename, ConfigVariable::ignore, ConfigVariable::name, ConfigVariable::next, palloc(), pstrdup(), ConfigVariable::sourceline, and ConfigVariable::value.

Referenced by ParseConfigDirectory(), ParseConfigFile(), ParseConfigFp(), and ProcessConfigFileInternal().