* Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options.
*
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.27 2001/01/09 06:24:33 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.28 2001/01/24 18:37:31 momjian Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
enum config_type
{
- PGC_NONE = 0,
- PGC_BOOL,
- PGC_INT,
- PGC_REAL,
- PGC_STRING
+ PGC_NONE = 0,
+ PGC_BOOL,
+ PGC_INT,
+ PGC_REAL,
+ PGC_STRING
};
struct config_generic
{
- const char *name;
- GucContext context;
- void *variable;
+ const char *name;
+ GucContext context;
+ void *variable;
};
struct config_bool
{
- const char *name;
- GucContext context;
- bool *variable;
- bool default_val;
+ const char *name;
+ GucContext context;
+ bool *variable;
+ bool default_val;
};
struct config_int
{
- const char *name;
- GucContext context;
- int *variable;
- int default_val;
- int min;
- int max;
+ const char *name;
+ GucContext context;
+ int *variable;
+ int default_val;
+ int min;
+ int max;
};
struct config_real
{
- const char *name;
- GucContext context;
- double *variable;
- double default_val;
- double min;
- double max;
+ const char *name;
+ GucContext context;
+ double *variable;
+ double default_val;
+ double min;
+ double max;
};
/*
*/
struct config_string
{
- const char *name;
- GucContext context;
- char **variable;
- const char *default_val;
- bool (*parse_hook)(const char *);
+ const char *name;
+ GucContext context;
+ char **variable;
+ const char *default_val;
+ bool (*parse_hook)(const char *);
};
*
* 4. Add a record below.
*
- * 5. Don't forget to document that option.
+ * 5. Add it to postgresql.conf.sample
+ *
+ * 6. Don't forget to document that option.
+ *
+ * WHEN MAKING MODIFICATIONS, remember to update postgresql.conf.sample
+ *
*/
{"commit_delay", PGC_USERSET, &CommitDelay,
5, 0, 1000},
- {NULL, 0, NULL, 0, 0, 0}
+ {NULL, 0, NULL, 0, 0, 0}
};
static struct config_real
ConfigureNamesReal[] =
{
- {"effective_cache_size", PGC_USERSET, &effective_cache_size,
- DEFAULT_EFFECTIVE_CACHE_SIZE, 0, DBL_MAX},
- {"random_page_cost", PGC_USERSET, &random_page_cost,
- DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX},
- {"cpu_tuple_cost", PGC_USERSET, &cpu_tuple_cost,
- DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX},
- {"cpu_index_tuple_cost", PGC_USERSET, &cpu_index_tuple_cost,
- DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX},
- {"cpu_operator_cost", PGC_USERSET, &cpu_operator_cost,
- DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX},
-
- {"geqo_selection_bias", PGC_USERSET, &Geqo_selection_bias,
- DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS, MAX_GEQO_SELECTION_BIAS},
-
- {NULL, 0, NULL, 0.0, 0.0, 0.0}
+ {"effective_cache_size", PGC_USERSET, &effective_cache_size,
+ DEFAULT_EFFECTIVE_CACHE_SIZE, 0, DBL_MAX},
+ {"random_page_cost", PGC_USERSET, &random_page_cost,
+ DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX},
+ {"cpu_tuple_cost", PGC_USERSET, &cpu_tuple_cost,
+ DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX},
+ {"cpu_index_tuple_cost", PGC_USERSET, &cpu_index_tuple_cost,
+ DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX},
+ {"cpu_operator_cost", PGC_USERSET, &cpu_operator_cost,
+ DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX},
+
+ {"geqo_selection_bias", PGC_USERSET, &Geqo_selection_bias,
+ DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS, MAX_GEQO_SELECTION_BIAS},
+
+ {NULL, 0, NULL, 0.0, 0.0, 0.0}
};
"", NULL},
#ifdef ENABLE_SYSLOG
- {"syslog_facility", PGC_POSTMASTER, &Syslog_facility,
- "LOCAL0", check_facility},
- {"syslog_ident", PGC_POSTMASTER, &Syslog_ident,
- "postgres", NULL},
+ {"syslog_facility", PGC_POSTMASTER, &Syslog_facility,
+ "LOCAL0", check_facility},
+ {"syslog_ident", PGC_POSTMASTER, &Syslog_ident,
+ "postgres", NULL},
#endif
{"unix_socket_directory", PGC_POSTMASTER, &UnixSocketDir,
static enum config_type
find_option(const char * name, struct config_generic ** record)
{
- int i;
-
- Assert(name);
-
- for (i = 0; ConfigureNamesBool[i].name; i++)
- if (strcasecmp(ConfigureNamesBool[i].name, name)==0)
- {
- if (record)
- *record = (struct config_generic *)&ConfigureNamesBool[i];
- return PGC_BOOL;
- }
-
- for (i = 0; ConfigureNamesInt[i].name; i++)
- if (strcasecmp(ConfigureNamesInt[i].name, name)==0)
- {
- if (record)
- *record = (struct config_generic *)&ConfigureNamesInt[i];
- return PGC_INT;
- }
-
- for (i = 0; ConfigureNamesReal[i].name; i++)
- if (strcasecmp(ConfigureNamesReal[i].name, name)==0)
- {
- if (record)
- *record = (struct config_generic *)&ConfigureNamesReal[i];
- return PGC_REAL;
- }
+ int i;
+
+ Assert(name);
+
+ for (i = 0; ConfigureNamesBool[i].name; i++)
+ if (strcasecmp(ConfigureNamesBool[i].name, name)==0)
+ {
+ if (record)
+ *record = (struct config_generic *)&ConfigureNamesBool[i];
+ return PGC_BOOL;
+ }
+
+ for (i = 0; ConfigureNamesInt[i].name; i++)
+ if (strcasecmp(ConfigureNamesInt[i].name, name)==0)
+ {
+ if (record)
+ *record = (struct config_generic *)&ConfigureNamesInt[i];
+ return PGC_INT;
+ }
+
+ for (i = 0; ConfigureNamesReal[i].name; i++)
+ if (strcasecmp(ConfigureNamesReal[i].name, name)==0)
+ {
+ if (record)
+ *record = (struct config_generic *)&ConfigureNamesReal[i];
+ return PGC_REAL;
+ }
for (i = 0; ConfigureNamesString[i].name; i++)
- if (strcasecmp(ConfigureNamesString[i].name, name)==0)
- {
- if (record)
- *record = (struct config_generic *)&ConfigureNamesString[i];
- return PGC_STRING;
- }
-
- return PGC_NONE;
+ if (strcasecmp(ConfigureNamesString[i].name, name)==0)
+ {
+ if (record)
+ *record = (struct config_generic *)&ConfigureNamesString[i];
+ return PGC_STRING;
+ }
+
+ return PGC_NONE;
}
void
ResetAllOptions(void)
{
- int i;
+ int i;
- for (i = 0; ConfigureNamesBool[i].name; i++)
- *(ConfigureNamesBool[i].variable) = ConfigureNamesBool[i].default_val;
+ for (i = 0; ConfigureNamesBool[i].name; i++)
+ *(ConfigureNamesBool[i].variable) = ConfigureNamesBool[i].default_val;
- for (i = 0; ConfigureNamesInt[i].name; i++)
- *(ConfigureNamesInt[i].variable) = ConfigureNamesInt[i].default_val;
+ for (i = 0; ConfigureNamesInt[i].name; i++)
+ *(ConfigureNamesInt[i].variable) = ConfigureNamesInt[i].default_val;
- for (i = 0; ConfigureNamesReal[i].name; i++)
- *(ConfigureNamesReal[i].variable) = ConfigureNamesReal[i].default_val;
+ for (i = 0; ConfigureNamesReal[i].name; i++)
+ *(ConfigureNamesReal[i].variable) = ConfigureNamesReal[i].default_val;
for (i = 0; ConfigureNamesString[i].name; i++)
{
static bool
parse_bool(const char * value, bool * result)
{
- size_t len = strlen(value);
-
- if (strncasecmp(value, "true", len)==0)
- {
- if (result)
- *result = true;
- }
- else if (strncasecmp(value, "false", len)==0)
- {
- if (result)
- *result = false;
- }
-
- else if (strncasecmp(value, "yes", len)==0)
- {
- if (result)
- *result = true;
- }
- else if (strncasecmp(value, "no", len)==0)
- {
- if (result)
- *result = false;
- }
-
- else if (strcasecmp(value, "on")==0)
- {
- if (result)
- *result = true;
- }
- else if (strcasecmp(value, "off")==0)
- {
- if (result)
- *result = false;
- }
-
- else if (strcasecmp(value, "1")==0)
- {
- if (result)
- *result = true;
- }
- else if (strcasecmp(value, "0")==0)
- {
- if (result)
- *result = false;
- }
-
- else
- return false;
- return true;
+ size_t len = strlen(value);
+
+ if (strncasecmp(value, "true", len)==0)
+ {
+ if (result)
+ *result = true;
+ }
+ else if (strncasecmp(value, "false", len)==0)
+ {
+ if (result)
+ *result = false;
+ }
+
+ else if (strncasecmp(value, "yes", len)==0)
+ {
+ if (result)
+ *result = true;
+ }
+ else if (strncasecmp(value, "no", len)==0)
+ {
+ if (result)
+ *result = false;
+ }
+
+ else if (strcasecmp(value, "on")==0)
+ {
+ if (result)
+ *result = true;
+ }
+ else if (strcasecmp(value, "off")==0)
+ {
+ if (result)
+ *result = false;
+ }
+
+ else if (strcasecmp(value, "1")==0)
+ {
+ if (result)
+ *result = true;
+ }
+ else if (strcasecmp(value, "0")==0)
+ {
+ if (result)
+ *result = false;
+ }
+
+ else
+ return false;
+ return true;
}
static bool
parse_int(const char * value, int * result)
{
- long val;
- char * endptr;
-
- errno = 0;
- val = strtol(value, &endptr, 0);
- if (endptr == value || *endptr != '\0' || errno == ERANGE)
- return false;
- if (result)
- *result = (int)val;
- return true;
+ long val;
+ char * endptr;
+
+ errno = 0;
+ val = strtol(value, &endptr, 0);
+ if (endptr == value || *endptr != '\0' || errno == ERANGE)
+ return false;
+ if (result)
+ *result = (int)val;
+ return true;
}
static bool
parse_real(const char * value, double * result)
{
- double val;
- char * endptr;
-
- errno = 0;
- val = strtod(value, &endptr);
- if (endptr == value || *endptr != '\0' || errno == ERANGE)
- return false;
- if (result)
- *result = val;
- return true;
+ double val;
+ char * endptr;
+
+ errno = 0;
+ val = strtod(value, &endptr);
+ if (endptr == value || *endptr != '\0' || errno == ERANGE)
+ return false;
+ if (result)
+ *result = val;
+ return true;
}
set_config_option(const char * name, const char * value, GucContext
context, bool DoIt)
{
- struct config_generic * record;
- enum config_type type;
+ struct config_generic * record;
+ enum config_type type;
int elevel;
elevel = (context == PGC_SIGHUP) ? DEBUG : ERROR;
- type = find_option(name, &record);
- if (type == PGC_NONE)
+ type = find_option(name, &record);
+ if (type == PGC_NONE)
{
elog(elevel, "'%s' is not a valid option name", name);
return false;
* precise rules. Note that we don't want to throw errors if we're
* in the SIGHUP context. In that case we just ignore the attempt.
*/
- if (record->context == PGC_POSTMASTER && context != PGC_POSTMASTER)
+ if (record->context == PGC_POSTMASTER && context != PGC_POSTMASTER)
{
if (context != PGC_SIGHUP)
elog(ERROR, "'%s' cannot be changed after server start", name);
/*
* Evaluate value and set variable
*/
- switch(type)
- {
- case PGC_BOOL:
+ switch(type)
+ {
+ case PGC_BOOL:
{
struct config_bool * conf = (struct config_bool *)record;
- if (value)
- {
+ if (value)
+ {
bool boolval;
- if (!parse_bool(value, &boolval))
+ if (!parse_bool(value, &boolval))
{
elog(elevel, "option '%s' requires a boolean value", name);
return false;
}
if (DoIt)
*conf->variable = boolval;
- }
- else if (DoIt)
- *conf->variable = conf->default_val;
- break;
+ }
+ else if (DoIt)
+ *conf->variable = conf->default_val;
+ break;
}
case PGC_INT:
- {
- struct config_int * conf = (struct config_int *)record;
+ {
+ struct config_int * conf = (struct config_int *)record;
- if (value)
- {
- int intval;
+ if (value)
+ {
+ int intval;
- if (!parse_int(value, &intval))
+ if (!parse_int(value, &intval))
{
- elog(elevel, "option '%s' expects an integer value", name);
+ elog(elevel, "option '%s' expects an integer value", name);
return false;
}
- if (intval < conf->min || intval > conf->max)
+ if (intval < conf->min || intval > conf->max)
{
- elog(elevel, "option '%s' value %d is outside"
+ elog(elevel, "option '%s' value %d is outside"
" of permissible range [%d .. %d]",
name, intval, conf->min, conf->max);
return false;
}
if (DoIt)
*conf->variable = intval;
- }
- else if (DoIt)
- *conf->variable = conf->default_val;
- break;
- }
+ }
+ else if (DoIt)
+ *conf->variable = conf->default_val;
+ break;
+ }
case PGC_REAL:
- {
- struct config_real * conf = (struct config_real *)record;
+ {
+ struct config_real * conf = (struct config_real *)record;
- if (value)
- {
- double dval;
+ if (value)
+ {
+ double dval;
- if (!parse_real(value, &dval))
+ if (!parse_real(value, &dval))
{
- elog(elevel, "option '%s' expects a real number", name);
+ elog(elevel, "option '%s' expects a real number", name);
return false;
}
- if (dval < conf->min || dval > conf->max)
+ if (dval < conf->min || dval > conf->max)
{
- elog(elevel, "option '%s' value %g is outside"
+ elog(elevel, "option '%s' value %g is outside"
" of permissible range [%g .. %g]",
name, dval, conf->min, conf->max);
return false;
}
if (DoIt)
*conf->variable = dval;
- }
- else if (DoIt)
- *conf->variable = conf->default_val;
- break;
- }
+ }
+ else if (DoIt)
+ *conf->variable = conf->default_val;
+ break;
+ }
case PGC_STRING:
{
}
default: ;
- }
+ }
return true;
}
const char *
GetConfigOption(const char * name)
{
- struct config_generic * record;
+ struct config_generic * record;
static char buffer[256];
enum config_type opttype;
- opttype = find_option(name, &record);
+ opttype = find_option(name, &record);
if (opttype == PGC_NONE)
elog(ERROR, "Option '%s' is not recognized", name);
switch(opttype)
- {
- case PGC_BOOL:
- return *((struct config_bool *)record)->variable ? "on" : "off";
+ {
+ case PGC_BOOL:
+ return *((struct config_bool *)record)->variable ? "on" : "off";
- case PGC_INT:
+ case PGC_INT:
snprintf(buffer, 256, "%d", *((struct config_int *)record)->variable);
return buffer;
- case PGC_REAL:
+ case PGC_REAL:
snprintf(buffer, 256, "%g", *((struct config_real *)record)->variable);
return buffer;
case PGC_STRING:
return *((struct config_string *)record)->variable;
- default:
+ default:
;
- }
- return NULL;
-}
+ }
+ return NULL;
+}
#ifdef ENABLE_SYSLOG
-bool
+bool
check_facility(const char *facility)
{
if (strcasecmp(facility,"LOCAL0") == 0) return true;