Commit 2938eec7 authored by Tom Lane's avatar Tom Lane

Extend GUC concepts of parse_hook and assign_hook to all four supported

datatypes, not only strings.  parse_hook is useless for bool, I suppose,
but it seems possibly useful for int and double to apply variable-specific
constraints that are more complex than simple range limits.  assign_hook
is definitely useful for all datatypes --- we need it right now for bool
to support date cache reset when changing Australian timezone rule setting.
Also, clean up some residual problems with the reset all/show all patch,
including memory leaks and mistaken reset of PostPortNumber.  It seems
best that RESET ALL not touch variables that don't have SUSET or
USERSET context.
parent 89765fa5
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.108 2001/06/03 14:53:56 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.109 2001/06/12 22:54:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -243,7 +243,7 @@ BootstrapMain(int argc, char *argv[]) ...@@ -243,7 +243,7 @@ BootstrapMain(int argc, char *argv[])
dbName = NULL; dbName = NULL;
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
ResetAllOptions(); ResetAllOptions(true);
potential_DataDir = getenv("PGDATA"); /* Null if no PGDATA potential_DataDir = getenv("PGDATA"); /* Null if no PGDATA
* variable */ * variable */
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.49 2001/06/07 04:50:56 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.50 2001/06/12 22:54:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -792,7 +792,9 @@ ResetPGVariable(const char *name) ...@@ -792,7 +792,9 @@ ResetPGVariable(const char *name)
reset_datestyle(); reset_datestyle();
reset_timezone(); reset_timezone();
ResetAllOptions(); ResetAllOptions(false);
} else } else
SetConfigOption(name, NULL, superuser() ? PGC_SUSET : PGC_USERSET, false); SetConfigOption(name, NULL,
superuser() ? PGC_SUSET : PGC_USERSET,
false);
} }
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.218 2001/06/11 04:12:29 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.219 2001/06/12 22:54:05 tgl Exp $
* *
* NOTES * NOTES
* *
...@@ -362,9 +362,13 @@ PostmasterMain(int argc, char *argv[]) ...@@ -362,9 +362,13 @@ PostmasterMain(int argc, char *argv[])
/* /*
* Options setup * Options setup
*/ */
potential_DataDir = getenv("PGDATA"); /* default value */ ResetAllOptions(true);
/* PGPORT environment variable, if set, overrides GUC setting */
if (getenv("PGPORT"))
PostPortNumber = atoi(getenv("PGPORT"));
ResetAllOptions(); potential_DataDir = getenv("PGDATA"); /* default value */
/* /*
* First we must scan for a -D argument to get the data dir. Then read * First we must scan for a -D argument to get the data dir. Then read
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.219 2001/06/07 04:50:57 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.220 2001/06/12 22:54:06 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -1156,7 +1156,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha ...@@ -1156,7 +1156,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
ResetAllOptions(); ResetAllOptions(true);
potential_DataDir = getenv("PGDATA"); potential_DataDir = getenv("PGDATA");
} }
StatFp = stderr; StatFp = stderr;
...@@ -1709,7 +1709,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha ...@@ -1709,7 +1709,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.219 $ $Date: 2001/06/07 04:50:57 $\n"); puts("$Revision: 1.220 $ $Date: 2001/06/12 22:54:06 $\n");
} }
/* /*
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Support for grand unified configuration scheme, including SET * Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options. * command, configuration file, and command line options.
* *
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.37 2001/06/07 04:50:57 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.38 2001/06/12 22:54:06 tgl Exp $
* *
* Copyright 2000 by PostgreSQL Global Development Group * Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
...@@ -46,7 +46,6 @@ extern bool FixBTree; ...@@ -46,7 +46,6 @@ extern bool FixBTree;
extern char *Syslog_facility; extern char *Syslog_facility;
extern char *Syslog_ident; extern char *Syslog_ident;
static bool check_facility(const char *facility); static bool check_facility(const char *facility);
#endif #endif
/* /*
...@@ -54,7 +53,6 @@ static bool check_facility(const char *facility); ...@@ -54,7 +53,6 @@ static bool check_facility(const char *facility);
*/ */
#ifdef USE_ASSERT_CHECKING #ifdef USE_ASSERT_CHECKING
bool assert_enabled = true; bool assert_enabled = true;
#endif #endif
bool Debug_print_query = false; bool Debug_print_query = false;
bool Debug_print_plan = false; bool Debug_print_plan = false;
...@@ -76,7 +74,9 @@ bool SQL_inheritance = true; ...@@ -76,7 +74,9 @@ bool SQL_inheritance = true;
#endif #endif
/*
* Declarations for GUC tables
*/
enum config_type enum config_type
{ {
PGC_NONE = 0, PGC_NONE = 0,
...@@ -101,6 +101,8 @@ struct config_bool ...@@ -101,6 +101,8 @@ struct config_bool
GucContext context; GucContext context;
bool *variable; bool *variable;
bool default_val; bool default_val;
/* No need for parse_hook ... presumably both values are legal */
void (*assign_hook) (bool newval);
}; };
...@@ -112,6 +114,8 @@ struct config_int ...@@ -112,6 +114,8 @@ struct config_int
int default_val; int default_val;
int min; int min;
int max; int max;
bool (*parse_hook) (int proposed);
void (*assign_hook) (int newval);
}; };
...@@ -123,6 +127,8 @@ struct config_real ...@@ -123,6 +127,8 @@ struct config_real
double default_val; double default_val;
double min; double min;
double max; double max;
bool (*parse_hook) (double proposed);
void (*assign_hook) (double newval);
}; };
/* /*
...@@ -171,61 +177,61 @@ struct config_string ...@@ -171,61 +177,61 @@ struct config_string
static struct config_bool static struct config_bool
ConfigureNamesBool[] = ConfigureNamesBool[] =
{ {
{"enable_seqscan", PGC_USERSET, &enable_seqscan, true}, {"enable_seqscan", PGC_USERSET, &enable_seqscan, true, NULL},
{"enable_indexscan", PGC_USERSET, &enable_indexscan, true}, {"enable_indexscan", PGC_USERSET, &enable_indexscan, true, NULL},
{"enable_tidscan", PGC_USERSET, &enable_tidscan, true}, {"enable_tidscan", PGC_USERSET, &enable_tidscan, true, NULL},
{"enable_sort", PGC_USERSET, &enable_sort, true}, {"enable_sort", PGC_USERSET, &enable_sort, true, NULL},
{"enable_nestloop", PGC_USERSET, &enable_nestloop, true}, {"enable_nestloop", PGC_USERSET, &enable_nestloop, true, NULL},
{"enable_mergejoin", PGC_USERSET, &enable_mergejoin, true}, {"enable_mergejoin", PGC_USERSET, &enable_mergejoin, true, NULL},
{"enable_hashjoin", PGC_USERSET, &enable_hashjoin, true}, {"enable_hashjoin", PGC_USERSET, &enable_hashjoin, true, NULL},
{"ksqo", PGC_USERSET, &_use_keyset_query_optimizer, false}, {"ksqo", PGC_USERSET, &_use_keyset_query_optimizer, false, NULL},
{"geqo", PGC_USERSET, &enable_geqo, true}, {"geqo", PGC_USERSET, &enable_geqo, true, NULL},
{"tcpip_socket", PGC_POSTMASTER, &NetServer, false}, {"tcpip_socket", PGC_POSTMASTER, &NetServer, false, NULL},
{"ssl", PGC_POSTMASTER, &EnableSSL, false}, {"ssl", PGC_POSTMASTER, &EnableSSL, false, NULL},
{"fsync", PGC_SIGHUP, &enableFsync, true}, {"fsync", PGC_SIGHUP, &enableFsync, true, NULL},
{"silent_mode", PGC_POSTMASTER, &SilentMode, false}, {"silent_mode", PGC_POSTMASTER, &SilentMode, false, NULL},
{"log_connections", PGC_SIGHUP, &Log_connections, false}, {"log_connections", PGC_SIGHUP, &Log_connections, false, NULL},
{"log_timestamp", PGC_SIGHUP, &Log_timestamp, false}, {"log_timestamp", PGC_SIGHUP, &Log_timestamp, false, NULL},
{"log_pid", PGC_SIGHUP, &Log_pid, false}, {"log_pid", PGC_SIGHUP, &Log_pid, false, NULL},
#ifdef USE_ASSERT_CHECKING #ifdef USE_ASSERT_CHECKING
{"debug_assertions", PGC_USERSET, &assert_enabled, true}, {"debug_assertions", PGC_USERSET, &assert_enabled, true, NULL},
#endif #endif
{"debug_print_query", PGC_USERSET, &Debug_print_query, false}, {"debug_print_query", PGC_USERSET, &Debug_print_query, false, NULL},
{"debug_print_parse", PGC_USERSET, &Debug_print_parse, false}, {"debug_print_parse", PGC_USERSET, &Debug_print_parse, false, NULL},
{"debug_print_rewritten", PGC_USERSET, &Debug_print_rewritten, false}, {"debug_print_rewritten", PGC_USERSET, &Debug_print_rewritten, false, NULL},
{"debug_print_plan", PGC_USERSET, &Debug_print_plan, false}, {"debug_print_plan", PGC_USERSET, &Debug_print_plan, false, NULL},
{"debug_pretty_print", PGC_USERSET, &Debug_pretty_print, false}, {"debug_pretty_print", PGC_USERSET, &Debug_pretty_print, false, NULL},
{"show_parser_stats", PGC_USERSET, &Show_parser_stats, false}, {"show_parser_stats", PGC_USERSET, &Show_parser_stats, false, NULL},
{"show_planner_stats", PGC_USERSET, &Show_planner_stats, false}, {"show_planner_stats", PGC_USERSET, &Show_planner_stats, false, NULL},
{"show_executor_stats", PGC_USERSET, &Show_executor_stats, false}, {"show_executor_stats", PGC_USERSET, &Show_executor_stats, false, NULL},
{"show_query_stats", PGC_USERSET, &Show_query_stats, false}, {"show_query_stats", PGC_USERSET, &Show_query_stats, false, NULL},
#ifdef BTREE_BUILD_STATS #ifdef BTREE_BUILD_STATS
{"show_btree_build_stats", PGC_SUSET, &Show_btree_build_stats, false}, {"show_btree_build_stats", PGC_SUSET, &Show_btree_build_stats, false, NULL},
#endif #endif
{"trace_notify", PGC_USERSET, &Trace_notify, false}, {"trace_notify", PGC_USERSET, &Trace_notify, false, NULL},
#ifdef LOCK_DEBUG #ifdef LOCK_DEBUG
{"trace_locks", PGC_SUSET, &Trace_locks, false}, {"trace_locks", PGC_SUSET, &Trace_locks, false, NULL},
{"trace_userlocks", PGC_SUSET, &Trace_userlocks, false}, {"trace_userlocks", PGC_SUSET, &Trace_userlocks, false, NULL},
{"trace_spinlocks", PGC_SUSET, &Trace_spinlocks, false}, {"trace_spinlocks", PGC_SUSET, &Trace_spinlocks, false, NULL},
{"debug_deadlocks", PGC_SUSET, &Debug_deadlocks, false}, {"debug_deadlocks", PGC_SUSET, &Debug_deadlocks, false, NULL},
#endif #endif
{"hostname_lookup", PGC_SIGHUP, &HostnameLookup, false}, {"hostname_lookup", PGC_SIGHUP, &HostnameLookup, false, NULL},
{"show_source_port", PGC_SIGHUP, &ShowPortNumber, false}, {"show_source_port", PGC_SIGHUP, &ShowPortNumber, false, NULL},
{"sql_inheritance", PGC_USERSET, &SQL_inheritance, true}, {"sql_inheritance", PGC_USERSET, &SQL_inheritance, true, NULL},
{"fixbtree", PGC_POSTMASTER, &FixBTree, true}, {"fixbtree", PGC_POSTMASTER, &FixBTree, true, NULL},
{NULL, 0, NULL, false} {NULL, 0, NULL, false, NULL}
}; };
...@@ -233,22 +239,22 @@ static struct config_int ...@@ -233,22 +239,22 @@ static struct config_int
ConfigureNamesInt[] = ConfigureNamesInt[] =
{ {
{"geqo_threshold", PGC_USERSET, &geqo_rels, {"geqo_threshold", PGC_USERSET, &geqo_rels,
DEFAULT_GEQO_RELS, 2, INT_MAX}, DEFAULT_GEQO_RELS, 2, INT_MAX, NULL, NULL},
{"geqo_pool_size", PGC_USERSET, &Geqo_pool_size, {"geqo_pool_size", PGC_USERSET, &Geqo_pool_size,
DEFAULT_GEQO_POOL_SIZE, 0, MAX_GEQO_POOL_SIZE}, DEFAULT_GEQO_POOL_SIZE, 0, MAX_GEQO_POOL_SIZE, NULL, NULL},
{"geqo_effort", PGC_USERSET, &Geqo_effort, {"geqo_effort", PGC_USERSET, &Geqo_effort,
1, 1, INT_MAX}, 1, 1, INT_MAX, NULL, NULL},
{"geqo_generations", PGC_USERSET, &Geqo_generations, {"geqo_generations", PGC_USERSET, &Geqo_generations,
0, 0, INT_MAX}, 0, 0, INT_MAX, NULL, NULL},
{"geqo_random_seed", PGC_USERSET, &Geqo_random_seed, {"geqo_random_seed", PGC_USERSET, &Geqo_random_seed,
-1, INT_MIN, INT_MAX}, -1, INT_MIN, INT_MAX, NULL, NULL},
{"deadlock_timeout", PGC_POSTMASTER, &DeadlockTimeout, {"deadlock_timeout", PGC_POSTMASTER, &DeadlockTimeout,
1000, 0, INT_MAX}, 1000, 0, INT_MAX, NULL, NULL},
#ifdef ENABLE_SYSLOG #ifdef ENABLE_SYSLOG
{"syslog", PGC_SIGHUP, &Use_syslog, {"syslog", PGC_SIGHUP, &Use_syslog,
0, 0, 2}, 0, 0, 2, NULL, NULL},
#endif #endif
/* /*
...@@ -257,52 +263,52 @@ static struct config_int ...@@ -257,52 +263,52 @@ static struct config_int
* constraints here are partially unused. * constraints here are partially unused.
*/ */
{"max_connections", PGC_POSTMASTER, &MaxBackends, {"max_connections", PGC_POSTMASTER, &MaxBackends,
DEF_MAXBACKENDS, 1, MAXBACKENDS}, DEF_MAXBACKENDS, 1, MAXBACKENDS, NULL, NULL},
{"shared_buffers", PGC_POSTMASTER, &NBuffers, {"shared_buffers", PGC_POSTMASTER, &NBuffers,
DEF_NBUFFERS, 16, INT_MAX}, DEF_NBUFFERS, 16, INT_MAX, NULL, NULL},
{"port", PGC_POSTMASTER, &PostPortNumber, {"port", PGC_POSTMASTER, &PostPortNumber,
DEF_PGPORT, 1, 65535}, DEF_PGPORT, 1, 65535, NULL, NULL},
{"sort_mem", PGC_USERSET, &SortMem, {"sort_mem", PGC_USERSET, &SortMem,
512, 1, INT_MAX}, 512, 1, INT_MAX, NULL, NULL},
{"debug_level", PGC_USERSET, &DebugLvl, {"debug_level", PGC_USERSET, &DebugLvl,
0, 0, 16}, 0, 0, 16, NULL, NULL},
#ifdef LOCK_DEBUG #ifdef LOCK_DEBUG
{"trace_lock_oidmin", PGC_SUSET, &Trace_lock_oidmin, {"trace_lock_oidmin", PGC_SUSET, &Trace_lock_oidmin,
BootstrapObjectIdData, 1, INT_MAX}, BootstrapObjectIdData, 1, INT_MAX, NULL, NULL},
{"trace_lock_table", PGC_SUSET, &Trace_lock_table, {"trace_lock_table", PGC_SUSET, &Trace_lock_table,
0, 0, INT_MAX}, 0, 0, INT_MAX, NULL, NULL},
#endif #endif
{"max_expr_depth", PGC_USERSET, &max_expr_depth, {"max_expr_depth", PGC_USERSET, &max_expr_depth,
DEFAULT_MAX_EXPR_DEPTH, 10, INT_MAX}, DEFAULT_MAX_EXPR_DEPTH, 10, INT_MAX, NULL, NULL},
{"unix_socket_permissions", PGC_POSTMASTER, &Unix_socket_permissions, {"unix_socket_permissions", PGC_POSTMASTER, &Unix_socket_permissions,
0777, 0000, 0777}, 0777, 0000, 0777, NULL, NULL},
{"checkpoint_segments", PGC_SIGHUP, &CheckPointSegments, {"checkpoint_segments", PGC_SIGHUP, &CheckPointSegments,
3, 1, INT_MAX}, 3, 1, INT_MAX, NULL, NULL},
{"checkpoint_timeout", PGC_SIGHUP, &CheckPointTimeout, {"checkpoint_timeout", PGC_SIGHUP, &CheckPointTimeout,
300, 30, 3600}, 300, 30, 3600, NULL, NULL},
{"wal_buffers", PGC_POSTMASTER, &XLOGbuffers, {"wal_buffers", PGC_POSTMASTER, &XLOGbuffers,
8, 4, INT_MAX}, 8, 4, INT_MAX, NULL, NULL},
{"wal_files", PGC_SIGHUP, &XLOGfiles, {"wal_files", PGC_SIGHUP, &XLOGfiles,
0, 0, 64}, 0, 0, 64, NULL, NULL},
{"wal_debug", PGC_SUSET, &XLOG_DEBUG, {"wal_debug", PGC_SUSET, &XLOG_DEBUG,
0, 0, 16}, 0, 0, 16, NULL, NULL},
{"commit_delay", PGC_USERSET, &CommitDelay, {"commit_delay", PGC_USERSET, &CommitDelay,
0, 0, 100000}, 0, 0, 100000, NULL, NULL},
{"commit_siblings", PGC_USERSET, &CommitSiblings, {"commit_siblings", PGC_USERSET, &CommitSiblings,
5, 1, 1000}, 5, 1, 1000, NULL, NULL},
{NULL, 0, NULL, 0, 0, 0} {NULL, 0, NULL, 0, 0, 0, NULL, NULL}
}; };
...@@ -310,20 +316,21 @@ static struct config_real ...@@ -310,20 +316,21 @@ static struct config_real
ConfigureNamesReal[] = ConfigureNamesReal[] =
{ {
{"effective_cache_size", PGC_USERSET, &effective_cache_size, {"effective_cache_size", PGC_USERSET, &effective_cache_size,
DEFAULT_EFFECTIVE_CACHE_SIZE, 0, DBL_MAX}, DEFAULT_EFFECTIVE_CACHE_SIZE, 0, DBL_MAX, NULL, NULL},
{"random_page_cost", PGC_USERSET, &random_page_cost, {"random_page_cost", PGC_USERSET, &random_page_cost,
DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX}, DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX, NULL, NULL},
{"cpu_tuple_cost", PGC_USERSET, &cpu_tuple_cost, {"cpu_tuple_cost", PGC_USERSET, &cpu_tuple_cost,
DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX}, DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX, NULL, NULL},
{"cpu_index_tuple_cost", PGC_USERSET, &cpu_index_tuple_cost, {"cpu_index_tuple_cost", PGC_USERSET, &cpu_index_tuple_cost,
DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX}, DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX, NULL, NULL},
{"cpu_operator_cost", PGC_USERSET, &cpu_operator_cost, {"cpu_operator_cost", PGC_USERSET, &cpu_operator_cost,
DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX}, DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX, NULL, NULL},
{"geqo_selection_bias", PGC_USERSET, &Geqo_selection_bias, {"geqo_selection_bias", PGC_USERSET, &Geqo_selection_bias,
DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS, MAX_GEQO_SELECTION_BIAS}, DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS,
MAX_GEQO_SELECTION_BIAS, NULL, NULL},
{NULL, 0, NULL, 0.0, 0.0, 0.0} {NULL, 0, NULL, 0.0, 0.0, 0.0, NULL, NULL}
}; };
...@@ -413,47 +420,84 @@ find_option(const char *name, struct config_generic ** record) ...@@ -413,47 +420,84 @@ find_option(const char *name, struct config_generic ** record)
/* /*
* Reset all options to their specified default values. Should only be * Reset all options to their specified default values. Must be called
* called at program startup. * with isStartup = true at program startup. May be called later with
* isStartup = false to reset all resettable options.
*/ */
void void
ResetAllOptions(void) ResetAllOptions(bool isStartup)
{ {
int i; int i;
for (i = 0; ConfigureNamesBool[i].name; i++) for (i = 0; ConfigureNamesBool[i].name; i++)
*(ConfigureNamesBool[i].variable) = ConfigureNamesBool[i].default_val; {
struct config_bool *conf = &ConfigureNamesBool[i];
if (isStartup ||
conf->context == PGC_SUSET || conf->context == PGC_USERSET)
{
if (conf->assign_hook)
(conf->assign_hook) (conf->default_val);
*conf->variable = conf->default_val;
}
}
for (i = 0; ConfigureNamesInt[i].name; i++) for (i = 0; ConfigureNamesInt[i].name; i++)
*(ConfigureNamesInt[i].variable) = ConfigureNamesInt[i].default_val; {
struct config_int *conf = &ConfigureNamesInt[i];
if (isStartup ||
conf->context == PGC_SUSET || conf->context == PGC_USERSET)
{
if (conf->assign_hook)
(conf->assign_hook) (conf->default_val);
*conf->variable = conf->default_val;
}
}
for (i = 0; ConfigureNamesReal[i].name; i++) for (i = 0; ConfigureNamesReal[i].name; i++)
*(ConfigureNamesReal[i].variable) = ConfigureNamesReal[i].default_val; {
struct config_real *conf = &ConfigureNamesReal[i];
if (isStartup ||
conf->context == PGC_SUSET || conf->context == PGC_USERSET)
{
if (conf->assign_hook)
(conf->assign_hook) (conf->default_val);
*conf->variable = conf->default_val;
}
}
for (i = 0; ConfigureNamesString[i].name; i++) for (i = 0; ConfigureNamesString[i].name; i++)
{
struct config_string *conf = &ConfigureNamesString[i];
if (isStartup ||
conf->context == PGC_SUSET || conf->context == PGC_USERSET)
{ {
char *str = NULL; char *str = NULL;
if (!ConfigureNamesString[i].default_val if (conf->default_val == NULL &&
&& ConfigureNamesString[i].boot_default_val) conf->boot_default_val)
{ {
str = strdup(ConfigureNamesString[i].boot_default_val); str = strdup(conf->boot_default_val);
if (str == NULL) if (str == NULL)
elog(ERROR, "out of memory"); elog(ERROR, "out of memory");
conf->default_val = str;
ConfigureNamesString[i].default_val = str;
} }
if (ConfigureNamesString[i].default_val) if (conf->default_val)
{ {
str = strdup(ConfigureNamesString[i].default_val); str = strdup(conf->default_val);
if (str == NULL) if (str == NULL)
elog(ERROR, "out of memory"); elog(ERROR, "out of memory");
} }
*(ConfigureNamesString[i].variable) = str; if (conf->assign_hook)
(conf->assign_hook) (str);
if (*conf->variable)
free(*conf->variable);
*conf->variable = str;
}
} }
if (getenv("PGPORT"))
PostPortNumber = atoi(getenv("PGPORT"));
} }
...@@ -591,8 +635,8 @@ parse_real(const char *value, double *result) ...@@ -591,8 +635,8 @@ parse_real(const char *value, double *result)
* See also SetConfigOption for an external interface. * See also SetConfigOption for an external interface.
*/ */
bool bool
set_config_option(const char *name, const char *value, GucContext set_config_option(const char *name, const char *value,
context, bool DoIt, bool makeDefault) GucContext context, bool DoIt, bool makeDefault)
{ {
struct config_generic *record; struct config_generic *record;
enum config_type type; enum config_type type;
...@@ -639,8 +683,8 @@ set_config_option(const char *name, const char *value, GucContext ...@@ -639,8 +683,8 @@ set_config_option(const char *name, const char *value, GucContext
else else
return true; return true;
} }
else if (record->context == PGC_SUSET && (context == PGC_USERSET else if (record->context == PGC_SUSET &&
|| context == PGC_BACKEND)) (context == PGC_USERSET || context == PGC_BACKEND))
elog(ERROR, "permission denied"); elog(ERROR, "permission denied");
...@@ -662,15 +706,22 @@ set_config_option(const char *name, const char *value, GucContext ...@@ -662,15 +706,22 @@ set_config_option(const char *name, const char *value, GucContext
elog(elevel, "option '%s' requires a boolean value", name); elog(elevel, "option '%s' requires a boolean value", name);
return false; return false;
} }
/* no parse_hook needed for booleans */
if (DoIt) if (DoIt)
{ {
if (conf->assign_hook)
(conf->assign_hook) (boolval);
*conf->variable = boolval; *conf->variable = boolval;
if (makeDefault) if (makeDefault)
conf->default_val = boolval; conf->default_val = boolval;
} }
} }
else if (DoIt) else if (DoIt)
{
if (conf->assign_hook)
(conf->assign_hook) (conf->default_val);
*conf->variable = conf->default_val; *conf->variable = conf->default_val;
}
break; break;
} }
...@@ -694,15 +745,27 @@ set_config_option(const char *name, const char *value, GucContext ...@@ -694,15 +745,27 @@ set_config_option(const char *name, const char *value, GucContext
name, intval, conf->min, conf->max); name, intval, conf->min, conf->max);
return false; return false;
} }
if (conf->parse_hook && !(conf->parse_hook) (intval))
{
elog(elevel, "invalid value for option '%s': %d",
name, intval);
return false;
}
if (DoIt) if (DoIt)
{ {
if (conf->assign_hook)
(conf->assign_hook) (intval);
*conf->variable = intval; *conf->variable = intval;
if (makeDefault) if (makeDefault)
conf->default_val = intval; conf->default_val = intval;
} }
} }
else if (DoIt) else if (DoIt)
{
if (conf->assign_hook)
(conf->assign_hook) (conf->default_val);
*conf->variable = conf->default_val; *conf->variable = conf->default_val;
}
break; break;
} }
...@@ -726,15 +789,27 @@ set_config_option(const char *name, const char *value, GucContext ...@@ -726,15 +789,27 @@ set_config_option(const char *name, const char *value, GucContext
name, dval, conf->min, conf->max); name, dval, conf->min, conf->max);
return false; return false;
} }
if (conf->parse_hook && !(conf->parse_hook) (dval))
{
elog(elevel, "invalid value for option '%s': %g",
name, dval);
return false;
}
if (DoIt) if (DoIt)
{ {
if (conf->assign_hook)
(conf->assign_hook) (dval);
*conf->variable = dval; *conf->variable = dval;
if (makeDefault) if (makeDefault)
conf->default_val = dval; conf->default_val = dval;
} }
} }
else if (DoIt) else if (DoIt)
{
if (conf->assign_hook)
(conf->assign_hook) (conf->default_val);
*conf->variable = conf->default_val; *conf->variable = conf->default_val;
}
break; break;
} }
...@@ -746,7 +821,8 @@ set_config_option(const char *name, const char *value, GucContext ...@@ -746,7 +821,8 @@ set_config_option(const char *name, const char *value, GucContext
{ {
if (conf->parse_hook && !(conf->parse_hook) (value)) if (conf->parse_hook && !(conf->parse_hook) (value))
{ {
elog(elevel, "invalid value for option '%s': '%s'", name, value); elog(elevel, "invalid value for option '%s': '%s'",
name, value);
return false; return false;
} }
if (DoIt) if (DoIt)
...@@ -766,13 +842,13 @@ set_config_option(const char *name, const char *value, GucContext ...@@ -766,13 +842,13 @@ set_config_option(const char *name, const char *value, GucContext
*conf->variable = str; *conf->variable = str;
if (makeDefault) if (makeDefault)
{ {
if (conf->default_val)
free(conf->default_val);
str = strdup(value); str = strdup(value);
if (str == NULL) { if (str == NULL) {
elog(elevel, "out of memory"); elog(elevel, "out of memory");
return false; return false;
} }
if (conf->default_val)
free(conf->default_val);
conf->default_val = str; conf->default_val = str;
} }
} }
...@@ -789,7 +865,7 @@ set_config_option(const char *name, const char *value, GucContext ...@@ -789,7 +865,7 @@ set_config_option(const char *name, const char *value, GucContext
elog(elevel, "out of memory"); elog(elevel, "out of memory");
return false; return false;
} }
conf->boot_default_val = str; conf->default_val = str;
} }
str = strdup(conf->default_val); str = strdup(conf->default_val);
if (str == NULL) if (str == NULL)
...@@ -818,8 +894,8 @@ set_config_option(const char *name, const char *value, GucContext ...@@ -818,8 +894,8 @@ set_config_option(const char *name, const char *value, GucContext
* this is just the wrapper to be called from the outside. * this is just the wrapper to be called from the outside.
*/ */
void void
SetConfigOption(const char *name, const char *value, GucContext SetConfigOption(const char *name, const char *value,
context, bool makeDefault) GucContext context, bool makeDefault)
{ {
(void) set_config_option(name, value, context, true, makeDefault); (void) set_config_option(name, value, context, true, makeDefault);
} }
...@@ -829,9 +905,7 @@ SetConfigOption(const char *name, const char *value, GucContext ...@@ -829,9 +905,7 @@ SetConfigOption(const char *name, const char *value, GucContext
/* /*
* This is more or less the SHOW command. It returns a string with the * This is more or less the SHOW command. It returns a string with the
* value of the option `name'. If the option doesn't exist, throw an * value of the option `name'. If the option doesn't exist, throw an
* elog and don't return. issuper should be true if and only if the * elog and don't return.
* current user is a superuser. Normal users don't have read
* permission on all options.
* *
* The string is *not* allocated for modification and is really only * The string is *not* allocated for modification and is really only
* valid until the next call to configuration related functions. * valid until the next call to configuration related functions.
...@@ -853,11 +927,13 @@ GetConfigOption(const char *name) ...@@ -853,11 +927,13 @@ GetConfigOption(const char *name)
return *((struct config_bool *) record)->variable ? "on" : "off"; return *((struct config_bool *) record)->variable ? "on" : "off";
case PGC_INT: case PGC_INT:
snprintf(buffer, 256, "%d", *((struct config_int *) record)->variable); snprintf(buffer, sizeof(buffer), "%d",
*((struct config_int *) record)->variable);
return buffer; return buffer;
case PGC_REAL: case PGC_REAL:
snprintf(buffer, 256, "%g", *((struct config_real *) record)->variable); snprintf(buffer, sizeof(buffer), "%g",
*((struct config_real *) record)->variable);
return buffer; return buffer;
case PGC_STRING: case PGC_STRING:
...@@ -872,7 +948,7 @@ GetConfigOption(const char *name) ...@@ -872,7 +948,7 @@ GetConfigOption(const char *name)
static void static void
_ShowOption(enum config_type opttype, struct config_generic *record) _ShowOption(enum config_type opttype, struct config_generic *record)
{ {
static char buffer[256]; char buffer[256];
char *val; char *val;
switch (opttype) switch (opttype)
...@@ -881,12 +957,14 @@ _ShowOption(enum config_type opttype, struct config_generic *record) ...@@ -881,12 +957,14 @@ _ShowOption(enum config_type opttype, struct config_generic *record)
val = *((struct config_bool *) record)->variable ? "on" : "off"; val = *((struct config_bool *) record)->variable ? "on" : "off";
break; break;
case PGC_INT: case PGC_INT:
snprintf(buffer, 256, "%d", *((struct config_int *) record)->variable); snprintf(buffer, sizeof(buffer), "%d",
*((struct config_int *) record)->variable);
val = buffer; val = buffer;
break; break;
case PGC_REAL: case PGC_REAL:
snprintf(buffer, 256, "%g", *((struct config_real *) record)->variable); snprintf(buffer, sizeof(buffer), "%g",
*((struct config_real *) record)->variable);
val = buffer; val = buffer;
break; break;
...@@ -955,8 +1033,8 @@ ParseLongOption(const char *string, char **name, char **value) ...@@ -955,8 +1033,8 @@ ParseLongOption(const char *string, char **name, char **value)
elog(FATAL, "out of memory"); elog(FATAL, "out of memory");
} }
else else
/* no equal sign in string */
{ {
/* no equal sign in string */
*name = strdup(string); *name = strdup(string);
if (!*name) if (!*name)
elog(FATAL, "out of memory"); elog(FATAL, "out of memory");
...@@ -971,6 +1049,7 @@ ParseLongOption(const char *string, char **name, char **value) ...@@ -971,6 +1049,7 @@ ParseLongOption(const char *string, char **name, char **value)
#ifdef ENABLE_SYSLOG #ifdef ENABLE_SYSLOG
static bool static bool
check_facility(const char *facility) check_facility(const char *facility)
{ {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* External declarations pertaining to backend/utils/misc/guc.c and * External declarations pertaining to backend/utils/misc/guc.c and
* backend/utils/misc/guc-file.l * backend/utils/misc/guc-file.l
* *
* $Header: /cvsroot/pgsql/src/include/utils/guc.h,v 1.7 2001/06/07 04:50:57 momjian Exp $ * $Id: guc.h,v 1.8 2001/06/12 22:54:06 tgl Exp $
*/ */
#ifndef GUC_H #ifndef GUC_H
#define GUC_H #define GUC_H
...@@ -46,13 +46,15 @@ typedef enum ...@@ -46,13 +46,15 @@ typedef enum
} GucContext; } GucContext;
void SetConfigOption(const char *name, const char *value, GucContext context, bool makeDefault); extern void SetConfigOption(const char *name, const char *value,
const char *GetConfigOption(const char *name); GucContext context, bool makeDefault);
void ProcessConfigFile(GucContext context); extern const char *GetConfigOption(const char *name);
void ResetAllOptions(void); extern void ProcessConfigFile(GucContext context);
void ParseLongOption(const char *string, char **name, char **value); extern void ResetAllOptions(bool isStartup);
bool set_config_option(const char *name, const char *value, GucContext context, bool DoIt, bool makeDefault); extern void ParseLongOption(const char *string, char **name, char **value);
void ShowAllGUCConfig(void); extern bool set_config_option(const char *name, const char *value,
GucContext context, bool DoIt, bool makeDefault);
extern void ShowAllGUCConfig(void);
extern bool Debug_print_query; extern bool Debug_print_query;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment