guc.c
来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 2,468 行 · 第 1/5 页
C
2,468 行
{ /* Can't be set in postgresql.conf */ {"server_version", PGC_INTERNAL, UNGROUPED, gettext_noop("Shows the server version."), NULL, GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE }, &server_version_string, PG_VERSION, NULL, NULL }, { /* Not for general use --- used by SET SESSION AUTHORIZATION */ {"session_authorization", PGC_USERSET, UNGROUPED, gettext_noop("Shows the session user name."), NULL, GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE }, &session_authorization_string, NULL, assign_session_authorization, show_session_authorization },#ifdef HAVE_SYSLOG { {"syslog_facility", PGC_POSTMASTER, LOGGING_SYSLOG, gettext_noop("Sets the syslog \"facility\" to be used when syslog enabled."), gettext_noop("Valid values are LOCAL0, LOCAL1, LOCAL2, LOCAL3, " "LOCAL4, LOCAL5, LOCAL6, LOCAL7.") }, &Syslog_facility, "LOCAL0", assign_facility, NULL }, { {"syslog_ident", PGC_POSTMASTER, LOGGING_SYSLOG, gettext_noop("Sets the program name used to identify PostgreSQL messages " "in syslog."), NULL }, &Syslog_ident, "postgres", NULL, NULL },#endif { {"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE, gettext_noop("Sets the time zone for displaying and interpreting time stamps."), NULL }, &timezone_string, "UNKNOWN", assign_timezone, show_timezone }, { {"transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Shows the current transaction's isolation level."), NULL, GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE }, &XactIsoLevel_string, NULL, assign_XactIsoLevel, show_XactIsoLevel }, { {"unix_socket_group", PGC_POSTMASTER, CONN_AUTH_SETTINGS, gettext_noop("Sets the owning group of the Unix-domain socket."), gettext_noop("(The owning user of the socket is always the user " "that starts the server.)") }, &Unix_socket_group, "", NULL, NULL }, { {"unix_socket_directory", PGC_POSTMASTER, CONN_AUTH_SETTINGS, gettext_noop("Sets the directory where the Unix-domain socket will be created."), NULL }, &UnixSocketDir, "", NULL, NULL }, { {"virtual_host", PGC_POSTMASTER, CONN_AUTH_SETTINGS, gettext_noop("Sets the host name or IP address to listen to."), NULL }, &VirtualHost, "", NULL, NULL }, { {"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS, gettext_noop("Selects the method used for forcing WAL updates out to disk."), NULL }, &XLOG_sync_method, XLOG_sync_method_default, assign_xlog_sync_method, NULL }, /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL }};/******** end of options list ********//* * Actual lookup of variables is done through this single, sorted array. */struct config_generic **guc_variables;int num_guc_variables;static bool guc_dirty; /* TRUE if need to do commit/abort work */static bool reporting_enabled; /* TRUE to enable GUC_REPORT */static char *guc_string_workspace; /* for avoiding memory leaks */static int guc_var_compare(const void *a, const void *b);static void ReportGUCOption(struct config_generic * record);static char *_ShowOption(struct config_generic * record);/* * Build the sorted array. This is split out so that it could be * re-executed after startup (eg, we could allow loadable modules to * add vars, and then we'd need to re-sort). */voidbuild_guc_variables(void){ int num_vars = 0; struct config_generic **guc_vars; int i; for (i = 0; ConfigureNamesBool[i].gen.name; i++) { struct config_bool *conf = &ConfigureNamesBool[i]; /* Rather than requiring vartype to be filled in by hand, do this: */ conf->gen.vartype = PGC_BOOL; num_vars++; } for (i = 0; ConfigureNamesInt[i].gen.name; i++) { struct config_int *conf = &ConfigureNamesInt[i]; conf->gen.vartype = PGC_INT; num_vars++; } for (i = 0; ConfigureNamesReal[i].gen.name; i++) { struct config_real *conf = &ConfigureNamesReal[i]; conf->gen.vartype = PGC_REAL; num_vars++; } for (i = 0; ConfigureNamesString[i].gen.name; i++) { struct config_string *conf = &ConfigureNamesString[i]; conf->gen.vartype = PGC_STRING; num_vars++; } guc_vars = (struct config_generic **) malloc(num_vars * sizeof(struct config_generic *)); if (!guc_vars) ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); num_vars = 0; for (i = 0; ConfigureNamesBool[i].gen.name; i++) guc_vars[num_vars++] = &ConfigureNamesBool[i].gen; for (i = 0; ConfigureNamesInt[i].gen.name; i++) guc_vars[num_vars++] = &ConfigureNamesInt[i].gen; for (i = 0; ConfigureNamesReal[i].gen.name; i++) guc_vars[num_vars++] = &ConfigureNamesReal[i].gen; for (i = 0; ConfigureNamesString[i].gen.name; i++) guc_vars[num_vars++] = &ConfigureNamesString[i].gen; qsort((void *) guc_vars, num_vars, sizeof(struct config_generic *), guc_var_compare); if (guc_variables) free(guc_variables); guc_variables = guc_vars; num_guc_variables = num_vars;}/* * Look up option NAME. If it exists, return a pointer to its record, * else return NULL. */static struct config_generic *find_option(const char *name){ const char **key = &name; struct config_generic **res; Assert(name); /* * by equating const char ** with struct config_generic *, we are * assuming the name field is first in config_generic. */ res = (struct config_generic **) bsearch((void *) &key, (void *) guc_variables, num_guc_variables, sizeof(struct config_generic *), guc_var_compare); if (res) return *res; return NULL;}/* * comparator for qsorting and bsearching guc_variables array */static intguc_var_compare(const void *a, const void *b){ struct config_generic *confa = *(struct config_generic **) a; struct config_generic *confb = *(struct config_generic **) b; const char *namea; const char *nameb; /* * The temptation to use strcasecmp() here must be resisted, because * the array ordering has to remain stable across setlocale() calls. * So, build our own with a simple ASCII-only downcasing. */ namea = confa->name; nameb = confb->name; while (*namea && *nameb) { char cha = *namea++; char chb = *nameb++; if (cha >= 'A' && cha <= 'Z') cha += 'a' - 'A'; if (chb >= 'A' && chb <= 'Z') chb += 'a' - 'A'; if (cha != chb) return cha - chb; } if (*namea) return 1; /* a is longer */ if (*nameb) return -1; /* b is longer */ return 0;}/* * Initialize GUC options during program startup. */voidInitializeGUCOptions(void){ int i; char *env; /* * Build sorted array of all GUC variables. */ build_guc_variables(); /* * Load all variables with their compiled-in defaults, and initialize * status fields as needed. */ for (i = 0; i < num_guc_variables; i++) { struct config_generic *gconf = guc_variables[i]; gconf->status = 0; gconf->reset_source = PGC_S_DEFAULT; gconf->session_source = PGC_S_DEFAULT; gconf->tentative_source = PGC_S_DEFAULT; gconf->source = PGC_S_DEFAULT; switch (gconf->vartype) { case PGC_BOOL: { struct config_bool *conf = (struct config_bool *) gconf; if (conf->assign_hook) if (!(*conf->assign_hook) (conf->reset_val, true, false)) elog(FATAL, "failed to initialize %s to %d", conf->gen.name, (int) conf->reset_val); *conf->variable = conf->reset_val; conf->session_val = conf->reset_val; break; } case PGC_INT: { struct config_int *conf = (struct config_int *) gconf; Assert(conf->reset_val >= conf->min); Assert(conf->reset_val <= conf->max); /* * Check to make sure we only have valid * PGC_USERLIMITs */ Assert(conf->gen.context != PGC_USERLIMIT || strcmp(conf->gen.name, "log_min_duration_statement") == 0); if (conf->assign_hook) if (!(*conf->assign_hook) (conf->reset_val, true, false)) elog(FATAL, "failed to initialize %s to %d", conf->gen.name, conf->reset_val); *conf->variable = conf->reset_val; conf->session_val = conf->reset_val; break; } case PGC_REAL: { struct config_real *conf = (struct config_real *) gconf; Assert(conf->reset_val >= conf->min); Assert(conf->reset_val <= conf->max); Assert(conf->gen.context != PGC_USERLIMIT); if (conf->assign_hook) if (!(*conf->assign_hook) (conf->reset_val, true, false)) elog(FATAL, "failed to initialize %s to %g", conf->gen.name, conf->reset_val); *conf->variable = conf->reset_val; conf->session_val = conf->reset_val; break; } case PGC_STRING: { struct config_string *conf = (struct config_string *) gconf; char *str; /* * Check to make sure we only have valid * PGC_USERLIMITs */ Assert(conf->gen.context != PGC_USERLIMIT || conf->assign_hook == assign_log_min_messages || conf->assign_hook == assign_client_min_messages || conf->assign_hook == assign_min_error_statement); *conf->variable = NULL; conf->reset_val = NULL; conf->session_val = NULL; conf->tentative_val = NULL; if (conf->boot_val == NULL) { /* Cannot set value yet */ break; } str = strdup(conf->boot_val); if (str == NULL) ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); conf->reset_val = str; if (conf->assign_hook) { const char *newstr; newstr = (*conf->assign_hook) (str, true, false); if (newstr == NULL) { elog(FATAL, "failed to initialize %s to \"%s\"", conf->gen.name, str); } else if (newstr != str) { free(str); /* * See notes in set_config_option about * casting */ str = (char *) newstr; conf->reset_val = str; } } *conf->variable = str; conf->session_val = str; break; } } } guc_dirty = false; reporting_enabled = false; guc_string_workspace = NULL; /* * Prevent any attempt to override the transaction modes from * non-interactive sources. */ SetConfigOption("transaction_isolation", "default", PGC_POSTMASTER, PGC_S_OVERRIDE); SetConfigOption("transaction_read_only", "no", PGC_POSTMASTER, PGC_S_OVERRIDE); /* * For historical reasons, some GUC parameters can receive defaults * from environment variables. Process those settings. */ env = getenv("PGPORT"); if (env != NULL) SetConfigOption("port", env, PGC_POSTMASTER, PGC_S_ENV_VAR); env = getenv("PGDATESTYLE"); if (env != NULL) SetConfigOption("datestyle", env, PGC_POSTMASTER, PGC_S_ENV_VAR); env = getenv("TZ"); if (env != NULL) SetConfigOption("timezone", env, PGC_POSTMASTER, PGC_S_ENV_VAR); env = getenv("PGCLIENTENCODING"); if (env != NULL) SetConfigOption("client_encoding", env, PGC_POSTMASTER, PGC_S_ENV_VAR);}/* * Reset all options to their saved default values (implements RESET ALL) */voidResetAllOptions(void){ int i; for (i = 0; i < num_guc_variables; i++) { struct config_generic *gconf = guc_variables[i]; /* Don't reset non-SET-able values */ if (gconf->context != PGC_SUSET && gconf->context != PGC_USERLIMIT && gconf->context != PGC_USERSET) continue; /* Don't reset if special exclusion from RESET ALL */ if (gconf->flags & GUC_NO_RESET_ALL) continue; /* No need to reset if wasn't SET */ if (gconf->source <= PGC_S_OVERRIDE) continue; switch (gconf->vartype) { case PGC_BOOL: { struct config_bool *conf = (struct config_bool *) gconf; if (conf->assign_hook) if (!(*conf->assign_hook) (conf->reset_val, true, true)) elog(ERROR, "failed to reset %s", conf->gen.name); *conf->variable = conf->reset_val; conf->tentative_val = conf->reset_val; conf->gen.source = conf->gen.reset_source; conf->gen.tentative_source = conf->gen.reset_source; conf->gen.status |= GUC_HAVE_TENTATIVE; guc_dirty = true; break; } case PGC_INT: { struct config_int *conf = (struct config_int *) gconf; if (conf->assign_hook) if (!(*conf->assign_hook) (conf->reset_val, true, true)) elog(ERROR, "failed to reset %s", conf->gen.name); *conf->variable = conf->reset_val; conf->tentative_val = conf->reset_val;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?