📄 guc.c
字号:
NULL, assign_session_authorization, show_session_authorization }, { {"log_destination", PGC_SIGHUP, LOGGING_WHERE, gettext_noop("Sets the destination for server log output."), gettext_noop("Valid values are combinations of \"stderr\", \"syslog\", " "and \"eventlog\", depending on the platform."), GUC_LIST_INPUT }, &log_destination_string, "stderr", assign_log_destination, NULL }, { {"log_directory", PGC_SIGHUP, LOGGING_WHERE, gettext_noop("Sets the destination directory for log files."), gettext_noop("May be specified as relative to the data directory " "or as absolute path."), GUC_SUPERUSER_ONLY }, &Log_directory, "pg_log", assign_canonical_path, NULL }, { {"log_filename", PGC_SIGHUP, LOGGING_WHERE, gettext_noop("Sets the file name pattern for log files."), NULL, GUC_SUPERUSER_ONLY }, &Log_filename, "postgresql-%Y-%m-%d_%H%M%S.log", NULL, NULL },#ifdef HAVE_SYSLOG { {"syslog_facility", PGC_SIGHUP, LOGGING_WHERE, 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_str, "LOCAL0", assign_syslog_facility, NULL }, { {"syslog_ident", PGC_SIGHUP, LOGGING_WHERE, gettext_noop("Sets the program name used to identify PostgreSQL " "messages in syslog."), NULL }, &syslog_ident_str, "postgres", assign_syslog_ident, NULL },#endif { {"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE, gettext_noop("Sets the time zone for displaying and interpreting time stamps."), NULL, GUC_REPORT }, &timezone_string, "UNKNOWN", assign_timezone, show_timezone }, { {"transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Sets 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, GUC_SUPERUSER_ONLY }, &UnixSocketDir, "", assign_canonical_path, NULL }, { {"listen_addresses", PGC_POSTMASTER, CONN_AUTH_SETTINGS, gettext_noop("Sets the host name or IP address(es) to listen to."), NULL, GUC_LIST_INPUT }, &ListenAddresses, "localhost", 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 }, { {"custom_variable_classes", PGC_SIGHUP, CUSTOM_OPTIONS, gettext_noop("Sets the list of known custom variable classes."), NULL, GUC_LIST_INPUT | GUC_LIST_QUOTE }, &custom_variable_classes, NULL, assign_custom_variable_classes, NULL }, { {"data_directory", PGC_POSTMASTER, FILE_LOCATIONS, gettext_noop("Sets the server's data directory."), NULL, GUC_SUPERUSER_ONLY }, &data_directory, NULL, NULL, NULL }, { {"config_file", PGC_POSTMASTER, FILE_LOCATIONS, gettext_noop("Sets the server's main configuration file."), NULL, GUC_DISALLOW_IN_FILE | GUC_SUPERUSER_ONLY }, &ConfigFileName, NULL, NULL, NULL }, { {"hba_file", PGC_POSTMASTER, FILE_LOCATIONS, gettext_noop("Sets the server's \"hba\" configuration file"), NULL, GUC_SUPERUSER_ONLY }, &HbaFileName, NULL, NULL, NULL }, { {"ident_file", PGC_POSTMASTER, FILE_LOCATIONS, gettext_noop("Sets the server's \"ident\" configuration file"), NULL, GUC_SUPERUSER_ONLY }, &IdentFileName, NULL, NULL, NULL }, { {"external_pid_file", PGC_POSTMASTER, FILE_LOCATIONS, gettext_noop("Writes the postmaster PID to the specified file."), NULL, GUC_SUPERUSER_ONLY }, &external_pid_file, NULL, assign_canonical_path, NULL }, /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL }};/******** end of options list ********//* * To allow continued support of obsolete names for GUC variables, we apply * the following mappings to any unrecognized name. Note that an old name * should be mapped to a new one only if the new variable has very similar * semantics to the old. */static const char *const map_old_guc_names[] = { "sort_mem", "work_mem", "vacuum_mem", "maintenance_work_mem", NULL};/* * Actual lookup of variables is done through this single, sorted array. */static struct config_generic **guc_variables;/* Current number of variables contained in the vector */static int num_guc_variables;/* Vector capacity */static int size_guc_variables;static bool guc_dirty; /* TRUE if need to do commit/abort work */static bool reporting_enabled; /* TRUE to enable GUC_REPORT */static int guc_var_compare(const void *a, const void *b);static int guc_name_compare(const char *namea, const char *nameb);static void push_old_value(struct config_generic * gconf);static void ReportGUCOption(struct config_generic * record);static void ShowGUCConfigOption(const char *name, DestReceiver *dest);static void ShowAllGUCConfig(DestReceiver *dest);static char *_ShowOption(struct config_generic * record);/* * Some infrastructure for checking malloc/strdup/realloc calls */static void *guc_malloc(int elevel, size_t size){ void *data; data = malloc(size); if (data == NULL) ereport(elevel, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); return data;}static void *guc_realloc(int elevel, void *old, size_t size){ void *data; data = realloc(old, size); if (data == NULL) ereport(elevel, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); return data;}static char *guc_strdup(int elevel, const char *src){ char *data; data = strdup(src); if (data == NULL) ereport(elevel, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); return data;}/* * Support for assigning to a field of a string GUC item. Free the prior * value if it's not referenced anywhere else in the item (including stacked * states). */static voidset_string_field(struct config_string * conf, char **field, char *newval){ char *oldval = *field; GucStack *stack; /* Do the assignment */ *field = newval; /* Exit if any duplicate references, or if old value was NULL anyway */ if (oldval == NULL || oldval == *(conf->variable) || oldval == conf->reset_val || oldval == conf->tentative_val) return; for (stack = conf->gen.stack; stack; stack = stack->prev) { if (oldval == stack->tentative_val.stringval || oldval == stack->value.stringval) return; } /* Not used anymore, so free it */ free(oldval);}/* * Detect whether strval is referenced anywhere in a GUC string item */static boolstring_field_used(struct config_string * conf, char *strval){ GucStack *stack; if (strval == *(conf->variable) || strval == conf->reset_val || strval == conf->tentative_val) return true; for (stack = conf->gen.stack; stack; stack = stack->prev) { if (strval == stack->tentative_val.stringval || strval == stack->value.stringval) return true; } return false;}struct config_generic **get_guc_variables(void){ return guc_variables;}/* * 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 size_vars; 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++; } /* * Create table with 20% slack */ size_vars = num_vars + num_vars / 4; guc_vars = (struct config_generic **) guc_malloc(FATAL, size_vars * sizeof(struct config_generic *)); 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; if (guc_variables) free(guc_variables); guc_variables = guc_vars; num_guc_variables = num_vars; size_guc_variables = size_vars; qsort((void *) guc_variables, num_guc_variables, sizeof(struct config_generic *), guc_var_compare);}static boolis_custom_class(const char *name, int dotPos){ /* * assign_custom_variable_classes() has made sure no empty identifiers or * whitespace exists in the variable */ bool result = false; const char *ccs = GetConfigOption("custom_variable_classes"); if (ccs != NULL) { const char *start = ccs; for (;; ++ccs) { int c = *ccs; if (c == 0 || c == ',') { if (dotPos == ccs - start && strncmp(start, name, dotPos) == 0) { result = true; break; } if (c == 0) break; start = ccs + 1; } } } return result;}/* * Add a new GUC variable to the list of known variables. The * list is expanded if needed. */static booladd_guc_variable(struct config_generic * var, int elevel){ if (num_guc_variables + 1 >= size_guc_variables) { /* * Increase the vector by 25% */ int size_vars = size_guc_variables + size_guc_variables / 4; struct config_generic **guc_vars; if (size_vars == 0) { size_vars = 100; guc_vars = (struct config_generic **) guc_malloc(elevel, size_vars * sizeof(struct config_generic *)); } else { guc_vars = (struct config_generic **) guc_realloc(elevel, guc_variables, size_vars * sizeof(struct config_generic *)); } if (guc_vars == NULL) return false; /* out of memory */ guc_variables = guc_vars; size_guc_variables = size_vars; } guc_variables[num_guc_variables++] = var; qsort((void *) guc_variables, num_guc_variables, sizeof(struct config_generic *), guc_var_compare); return true;}/* * Create and add a placeholder variable. It's presumed to belong * to a valid custom variable class at this point. */static struct config_string *add_placeholder_variable(const char *name, int elevel){ size_t sz = sizeof(struct config_string) + sizeof(char *); struct config_string *var; struct config_generic *gen; var = (struct config_string *) guc_malloc(elevel, sz); if (v
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -