📄 guc-file.l
字号:
/* -*-pgsql-c-*- *//* * Scanner for the configuration file * * Copyright (c) 2000-2008, PostgreSQL Global Development Group * * $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.53 2008/01/01 19:45:54 momjian Exp $ */%{#include "postgres.h"#include <ctype.h>#include <unistd.h>#include "miscadmin.h"#include "storage/fd.h"#include "utils/guc.h"/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */#undef fprintf#define fprintf(file, fmt, msg) ereport(ERROR, (errmsg_internal("%s", msg)))enum { GUC_ID = 1, GUC_STRING = 2, GUC_INTEGER = 3, GUC_REAL = 4, GUC_EQUALS = 5, GUC_UNQUOTED_STRING = 6, GUC_QUALIFIED_ID = 7, GUC_EOL = 99, GUC_ERROR = 100};struct name_value_pair{ char *name; char *value; struct name_value_pair *next;};static unsigned int ConfigFileLineno;/* flex fails to supply a prototype for yylex, so provide one */int GUC_yylex(void);static bool ParseConfigFile(const char *config_file, const char *calling_file, int depth, GucContext context, int elevel, struct name_value_pair **head_p, struct name_value_pair **tail_p);static void free_name_value_list(struct name_value_pair * list);static char *GUC_scanstr(const char *s);%}%option 8bit%option never-interactive%option nodefault%option nounput%option noyywrap%option prefix="GUC_yy"SIGN ("-"|"+")DIGIT [0-9]HEXDIGIT [0-9a-fA-F]UNIT_LETTER [a-zA-Z]INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+){UNIT_LETTER}*EXPONENT [Ee]{SIGN}?{DIGIT}+REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}?LETTER [A-Za-z_\200-\377]LETTER_OR_DIGIT [A-Za-z_0-9\200-\377]ID {LETTER}{LETTER_OR_DIGIT}*QUALIFIED_ID {ID}"."{ID}UNQUOTED_STRING {LETTER}({LETTER_OR_DIGIT}|[-._:/])*STRING \'([^'\\\n]|\\.|\'\')*\'%%\n ConfigFileLineno++; return GUC_EOL;[ \t\r]+ /* eat whitespace */#.* /* eat comment (.* matches anything until newline) */{ID} return GUC_ID;{QUALIFIED_ID} return GUC_QUALIFIED_ID;{STRING} return GUC_STRING;{UNQUOTED_STRING} return GUC_UNQUOTED_STRING;{INTEGER} return GUC_INTEGER;{REAL} return GUC_REAL;= return GUC_EQUALS;. return GUC_ERROR;%%/* * Exported function to read and process the configuration file. The * parameter indicates in what context the file is being read --- either * postmaster startup (including standalone-backend startup) or SIGHUP. * All options mentioned in the configuration file are set to new values. * If an error occurs, no values will be changed. */voidProcessConfigFile(GucContext context){ int elevel; struct name_value_pair *item, *head, *tail; char *cvc = NULL; struct config_string *cvc_struct; const char *envvar; int i; Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP); if (context == PGC_SIGHUP) { /* * To avoid cluttering the log, only the postmaster bleats loudly * about problems with the config file. */ elevel = IsUnderPostmaster ? DEBUG2 : LOG; } else elevel = ERROR; /* Parse the file into a list of option names and values */ head = tail = NULL; if (!ParseConfigFile(ConfigFileName, NULL, 0, context, elevel, &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 * from the file since we last processed it. */ for (i = 0; i < num_guc_variables; i++) { struct config_generic *gconf = guc_variables[i]; gconf->status &= ~GUC_IS_IN_FILE; } /* * Check if all options are valid. As a side-effect, the GUC_IS_IN_FILE * flag is set on each GUC variable mentioned in the list. */ for (item = head; item; item = item->next) { char *sep = strchr(item->name, GUC_QUALIFIER_SEPARATOR); if (sep) { /* * We have to consider three cases for custom variables: * * 1. The class name is not valid according to the (new) setting * of custom_variable_classes. If so, reject. We don't care * which side is at fault. */ if (!is_custom_class(item->name, sep - item->name, cvc)) { ereport(elevel, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("unrecognized configuration parameter \"%s\"", item->name))); goto cleanup_list; } /* * 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, * since we could still fail further down the list. Do nothing * (assuming that making the placeholder will succeed later). */ if (find_option(item->name, false, elevel) == NULL) continue; /* * 3. There is already a GUC entry (either real or placeholder) for * the variable. In this case we should let set_config_option * check it, since the assignment could well fail if it's a real * entry. */ } if (!set_config_option(item->name, item->value, context, PGC_S_FILE, GUC_ACTION_SET, false)) goto cleanup_list; } /* * Check for variables having been removed from the config file, and * revert their reset values (and perhaps also effective values) to the * boot-time defaults. If such a variable can't be changed after startup, * just throw a warning and continue. (This is analogous to the fact that * set_config_option only throws a warning for a new but different value. * If we wanted to make it a hard error, we'd need an extra pass over the * list so that we could throw the error before starting to apply * changes.) */ for (i = 0; i < num_guc_variables; i++) { struct config_generic *gconf = guc_variables[i]; GucStack *stack; if (gconf->reset_source != PGC_S_FILE || (gconf->status & GUC_IS_IN_FILE)) continue; if (gconf->context < PGC_SIGHUP) { ereport(elevel, (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM), errmsg("parameter \"%s\" cannot be changed after server start; configuration file change ignored", gconf->name))); continue; } /* * Reset any "file" sources to "default", else set_config_option * will not override those settings. */ if (gconf->reset_source == PGC_S_FILE) gconf->reset_source = PGC_S_DEFAULT; if (gconf->source == PGC_S_FILE) gconf->source = PGC_S_DEFAULT; for (stack = gconf->stack; stack; stack = stack->prev) { if (stack->source == PGC_S_FILE) stack->source = PGC_S_DEFAULT; } /* Now we can re-apply the wired-in default */ set_config_option(gconf->name, NULL, context, PGC_S_DEFAULT, GUC_ACTION_SET, true); } /* * Restore any variables determined by environment variables. This * is a no-op except in the case where one of these had been in the * config file and is now removed. PGC_S_ENV_VAR will override the * wired-in default we just applied, but cannot override any other source. * * Keep this list in sync with InitializeGUCOptions()! * PGPORT can be ignored, because it cannot be changed without restart. * We assume rlimit hasn't changed, either. */ envvar = getenv("PGDATESTYLE"); if (envvar != NULL) set_config_option("datestyle", envvar, PGC_POSTMASTER, PGC_S_ENV_VAR, GUC_ACTION_SET, true); envvar = getenv("PGCLIENTENCODING"); if (envvar != NULL) set_config_option("client_encoding", envvar, PGC_POSTMASTER, PGC_S_ENV_VAR, GUC_ACTION_SET, true); /* If we got here all the options checked out okay, so apply them. */ for (item = head; item; item = item->next) { set_config_option(item->name, item->value, context, PGC_S_FILE, GUC_ACTION_SET, true); } cleanup_list: free_name_value_list(head); if (cvc) free(cvc);}/* * Read and parse a single configuration file. This function recurses * to handle "include" directives. * * Input parameters: * config_file: absolute or relative path of file to read
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -