guc
I was playing around with adding a couple new SET commands (REAL_FORMAT
and DOUBLE_PRECISION_FORMAT as per todo list item) and I ended up
playing with GUC a bit.
I've cleaned it up a bit - most of the changes should be fairly
self-explanitory from the patch. Some of the configuration options
handled in variable.c (so far, server_encoding and seed) have been moved
into guc.c and are handled by GUC. Moving them in required adding a
couple of fields to config_generic and friends - a read_only field and a
display_proc field (hook for custom SHOW messages). I've removed
GetConfigOption() and replaced it with ShowConfigOption() which does an
elog(NOTICE) instead of returning a string.
When setting REAL_FORMAT and DOUBLE_PRECISION_FORMAT, the printf-style
format string should be checked for certain things:
- field width of "*" is not allowed
- precision of ".*" is not allowed
- all conversion specifiers except "s" and "n" are allowed
- only one conversion specification other than %% and variations is
allowed
Does this seem reasonable to people? I haven't written a function to
check those yet.. will do soon.
This patch isn't complete yet so don't append it to the pending patches
list, Bruce.
Liam
--
Liam Stewart :: Red Hat Canada, Ltd. :: liams@redhat.com
Attachments:
patch.difftext/plain; charset=us-asciiDownload
Index: src/backend/commands/variable.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/variable.c,v
retrieving revision 1.57
diff -c -r1.57 variable.c
*** src/backend/commands/variable.c 2001/12/09 04:37:50 1.57
--- src/backend/commands/variable.c 2002/01/15 22:20:21
***************
*** 50,65 ****
static bool show_XactIsoLevel(void);
static bool reset_XactIsoLevel(void);
static bool parse_XactIsoLevel(List *);
- static bool show_random_seed(void);
- static bool reset_random_seed(void);
- static bool parse_random_seed(List *);
static bool show_client_encoding(void);
static bool reset_client_encoding(void);
static bool parse_client_encoding(List *);
- static bool show_server_encoding(void);
- static bool reset_server_encoding(void);
- static bool parse_server_encoding(List *);
/*
--- 50,59 ----
***************
*** 599,643 ****
/*
- * Random number seed
- */
- static bool
- parse_random_seed(List *args)
- {
- char *value;
- double seed = 0;
-
- if (args == NULL)
- return reset_random_seed();
-
- Assert(IsA(lfirst(args), A_Const));
-
- value = ((A_Const *) lfirst(args))->val.val.str;
-
- sscanf(value, "%lf", &seed);
- DirectFunctionCall1(setseed, Float8GetDatum(seed));
-
- return (TRUE);
- }
-
- static bool
- show_random_seed(void)
- {
- elog(NOTICE, "Seed for random number generator is unavailable");
- return (TRUE);
- }
-
- static bool
- reset_random_seed(void)
- {
- double seed = 0.5;
-
- DirectFunctionCall1(setseed, Float8GetDatum(seed));
- return (TRUE);
- }
-
-
- /*
* MULTIBYTE-related functions
*
* If MULTIBYTE support was not compiled, we still allow these variables
--- 593,598 ----
***************
*** 724,751 ****
}
- static bool
- parse_server_encoding(List *args)
- {
- elog(NOTICE, "SET SERVER_ENCODING is not supported");
- return TRUE;
- }
-
- static bool
- show_server_encoding(void)
- {
- elog(NOTICE, "Current server encoding is '%s'", GetDatabaseEncodingName());
- return TRUE;
- }
-
- static bool
- reset_server_encoding(void)
- {
- elog(NOTICE, "RESET SERVER_ENCODING is not supported");
- return TRUE;
- }
-
-
/* SetPGVariable()
* Dispatcher for handling SET commands.
--- 679,684 ----
***************
*** 762,771 ****
parse_XactIsoLevel(args);
else if (strcasecmp(name, "client_encoding") == 0)
parse_client_encoding(args);
- else if (strcasecmp(name, "server_encoding") == 0)
- parse_server_encoding(args);
- else if (strcasecmp(name, "seed") == 0)
- parse_random_seed(args);
else
{
/*
--- 695,700 ----
***************
*** 796,820 ****
show_XactIsoLevel();
else if (strcasecmp(name, "client_encoding") == 0)
show_client_encoding();
- else if (strcasecmp(name, "server_encoding") == 0)
- show_server_encoding();
- else if (strcasecmp(name, "seed") == 0)
- show_random_seed();
else if (strcasecmp(name, "all") == 0)
{
! ShowAllGUCConfig();
show_datestyle();
show_timezone();
show_XactIsoLevel();
- show_client_encoding();
- show_server_encoding();
- show_random_seed();
}
else
{
! const char *val = GetConfigOption(name);
!
! elog(NOTICE, "%s is %s", name, val);
}
}
--- 725,741 ----
show_XactIsoLevel();
else if (strcasecmp(name, "client_encoding") == 0)
show_client_encoding();
else if (strcasecmp(name, "all") == 0)
{
! ShowAllOptions();
!
show_datestyle();
show_timezone();
show_XactIsoLevel();
}
else
{
! ShowConfigOption(name);
}
}
***************
*** 829,842 ****
reset_XactIsoLevel();
else if (strcasecmp(name, "client_encoding") == 0)
reset_client_encoding();
- else if (strcasecmp(name, "server_encoding") == 0)
- reset_server_encoding();
- else if (strcasecmp(name, "seed") == 0)
- reset_random_seed();
else if (strcasecmp(name, "all") == 0)
{
- reset_random_seed();
- /* reset_server_encoding(); */
reset_client_encoding();
reset_datestyle();
reset_timezone();
--- 750,757 ----
***************
*** 844,850 ****
ResetAllOptions(false);
}
else
! SetConfigOption(name, NULL,
! superuser() ? PGC_SUSET : PGC_USERSET,
! false);
}
--- 759,764 ----
ResetAllOptions(false);
}
else
! ResetConfigOption(name, NULL,
! superuser() ? PGC_SUSET : PGC_USERSET);
}
Index: src/backend/utils/adt/float.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/float.c,v
retrieving revision 1.78
diff -c -r1.78 float.c
*** src/backend/utils/adt/float.c 2001/12/11 02:02:12 1.78
--- src/backend/utils/adt/float.c 2002/01/15 22:20:24
***************
*** 64,69 ****
--- 64,70 ----
#include "fmgr.h"
#include "utils/array.h"
#include "utils/builtins.h"
+ #include "miscadmin.h"
#if !(NeXT && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_2)
***************
*** 126,131 ****
--- 127,137 ----
#define FLOAT8_MAX DBL_MAX
#define FLOAT8_MIN DBL_MIN
+ /*
+ * formatting
+ */
+ char *Real_format;
+ char *Double_precision_format;
/*
check to see if a float4 val is outside of
***************
*** 237,243 ****
if (infflag < 0)
PG_RETURN_CSTRING(strcpy(ascii, "-Infinity"));
! sprintf(ascii, "%.*g", FLT_DIG, num);
PG_RETURN_CSTRING(ascii);
}
--- 243,249 ----
if (infflag < 0)
PG_RETURN_CSTRING(strcpy(ascii, "-Infinity"));
! sprintf(ascii, Real_format, num);
PG_RETURN_CSTRING(ascii);
}
***************
*** 299,305 ****
if (infflag < 0)
PG_RETURN_CSTRING(strcpy(ascii, "-Infinity"));
! sprintf(ascii, "%.*g", DBL_DIG, num);
PG_RETURN_CSTRING(ascii);
}
--- 305,311 ----
if (infflag < 0)
PG_RETURN_CSTRING(strcpy(ascii, "-Infinity"));
! sprintf(ascii, Double_precision_format, num);
PG_RETURN_CSTRING(ascii);
}
Index: src/backend/utils/misc/guc-file.l
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc-file.l,v
retrieving revision 1.9
diff -c -r1.9 guc-file.l
*** src/backend/utils/misc/guc-file.l 2001/08/06 13:45:15 1.9
--- src/backend/utils/misc/guc-file.l 2002/01/15 22:20:24
***************
*** 240,252 ****
*/
for(item = head; item; item=item->next)
{
! if (!set_config_option(item->name, item->value, context, false, false))
goto cleanup_exit;
}
/* If we got here all the options parsed okay. */
for(item = head; item; item=item->next)
! set_config_option(item->name, item->value, context, true, true);
cleanup_exit:
free_name_value_list(head);
--- 240,252 ----
*/
for(item = head; item; item=item->next)
{
! if (!CheckConfigOption(item->name, item->value, context))
goto cleanup_exit;
}
/* If we got here all the options parsed okay. */
for(item = head; item; item=item->next)
! SetConfigOption(item->name, item->value, context, true);
cleanup_exit:
free_name_value_list(head);
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.58
diff -c -r1.58 guc.c
*** src/backend/utils/misc/guc.c 2001/10/30 05:38:56 1.58
--- src/backend/utils/misc/guc.c 2002/01/15 22:20:25
***************
*** 37,44 ****
--- 37,51 ----
#include "storage/proc.h"
#include "tcop/tcopprot.h"
#include "utils/datetime.h"
+ #include "utils/builtins.h"
#include "pgstat.h"
+ #ifdef MULTIBYTE
+ #include "mb/pg_wchar.h"
+ #else
+ /* Grand unified hard-coded badness */
+ #define GetDatabaseEncodingName() "SQL_ASCII"
+ #endif
/* XXX these should be in other modules' header files */
extern bool Log_connections;
***************
*** 56,65 ****
--- 63,79 ----
#endif
static char *default_iso_level_string;
+ static double seed;
+ static bool set_config_option(const char *name, const char *value,
+ GucContext context, bool doIt,
+ bool makeDefault, bool reset);
static bool check_defaultxactisolevel(const char *value);
static void assign_defaultxactisolevel(const char *value);
+ static void display_server_encoding(void);
+ static void assign_seed(double newval);
+
/*
* Debugging options
*/
***************
*** 107,113 ****
--- 121,129 ----
{
const char *name;
GucContext context;
+ bool read_only;
void *variable;
+ void (*display_proc) (void);
};
***************
*** 115,121 ****
--- 131,140 ----
{
const char *name;
GucContext context;
+ bool read_only;
bool *variable;
+ void (*display_proc) (void);
+
bool default_val;
/* No need for parse_hook ... presumably both values are legal */
void (*assign_hook) (bool newval);
***************
*** 126,132 ****
--- 145,154 ----
{
const char *name;
GucContext context;
+ bool read_only;
int *variable;
+ void (*display_proc) (void);
+
int default_val;
int min;
int max;
***************
*** 139,145 ****
--- 161,170 ----
{
const char *name;
GucContext context;
+ bool read_only;
double *variable;
+ void (*display_proc) (void);
+
double default_val;
double min;
double max;
***************
*** 157,163 ****
--- 182,191 ----
{
const char *name;
GucContext context;
+ bool read_only;
char **variable;
+ void (*display_proc) (void);
+
const char *boot_default_val;
bool (*parse_hook) (const char *proposed);
void (*assign_hook) (const char *newval);
***************
*** 193,349 ****
ConfigureNamesBool[] =
{
{
! "enable_seqscan", PGC_USERSET, &enable_seqscan, true, NULL
},
{
! "enable_indexscan", PGC_USERSET, &enable_indexscan, true, NULL
},
{
! "enable_tidscan", PGC_USERSET, &enable_tidscan, true, NULL
},
{
! "enable_sort", PGC_USERSET, &enable_sort, true, NULL
},
{
! "enable_nestloop", PGC_USERSET, &enable_nestloop, true, NULL
},
{
! "enable_mergejoin", PGC_USERSET, &enable_mergejoin, true, NULL
},
{
! "enable_hashjoin", PGC_USERSET, &enable_hashjoin, true, NULL
},
{
! "ksqo", PGC_USERSET, &_use_keyset_query_optimizer, false, NULL
},
{
! "geqo", PGC_USERSET, &enable_geqo, true, NULL
},
{
! "tcpip_socket", PGC_POSTMASTER, &NetServer, false, NULL
},
{
! "ssl", PGC_POSTMASTER, &EnableSSL, false, NULL
},
{
! "fsync", PGC_SIGHUP, &enableFsync, true, NULL
},
{
! "silent_mode", PGC_POSTMASTER, &SilentMode, false, NULL
},
{
! "log_connections", PGC_BACKEND, &Log_connections, false, NULL
},
{
! "log_timestamp", PGC_SIGHUP, &Log_timestamp, false, NULL
},
{
! "log_pid", PGC_SIGHUP, &Log_pid, false, NULL
},
#ifdef USE_ASSERT_CHECKING
{
! "debug_assertions", PGC_USERSET, &assert_enabled, true, NULL
},
#endif
{
! "debug_print_query", PGC_USERSET, &Debug_print_query, false, NULL
},
{
! "debug_print_parse", PGC_USERSET, &Debug_print_parse, false, NULL
},
{
! "debug_print_rewritten", PGC_USERSET, &Debug_print_rewritten, false, NULL
},
{
! "debug_print_plan", PGC_USERSET, &Debug_print_plan, false, NULL
},
{
! "debug_pretty_print", PGC_USERSET, &Debug_pretty_print, false, NULL
},
{
! "show_parser_stats", PGC_USERSET, &Show_parser_stats, false, NULL
},
{
! "show_planner_stats", PGC_USERSET, &Show_planner_stats, false, NULL
},
{
! "show_executor_stats", PGC_USERSET, &Show_executor_stats, false, NULL
},
{
! "show_query_stats", PGC_USERSET, &Show_query_stats, false, NULL
},
#ifdef BTREE_BUILD_STATS
{
! "show_btree_build_stats", PGC_SUSET, &Show_btree_build_stats, false, NULL
},
#endif
{
! "stats_start_collector", PGC_POSTMASTER, &pgstat_collect_startcollector, true, NULL
},
{
! "stats_reset_on_server_start", PGC_POSTMASTER, &pgstat_collect_resetonpmstart, true, NULL
},
{
! "stats_command_string", PGC_SUSET, &pgstat_collect_querystring, false, NULL
},
{
! "stats_row_level", PGC_SUSET, &pgstat_collect_tuplelevel, false, NULL
},
{
! "stats_block_level", PGC_SUSET, &pgstat_collect_blocklevel, false, NULL
},
{
! "trace_notify", PGC_USERSET, &Trace_notify, false, NULL
},
#ifdef LOCK_DEBUG
{
! "trace_locks", PGC_SUSET, &Trace_locks, false, NULL
},
{
! "trace_userlocks", PGC_SUSET, &Trace_userlocks, false, NULL
},
{
! "trace_lwlocks", PGC_SUSET, &Trace_lwlocks, false, NULL
},
{
! "debug_deadlocks", PGC_SUSET, &Debug_deadlocks, false, NULL
},
#endif
{
! "hostname_lookup", PGC_SIGHUP, &HostnameLookup, false, NULL
},
{
! "show_source_port", PGC_SIGHUP, &ShowPortNumber, false, NULL
},
{
! "sql_inheritance", PGC_USERSET, &SQL_inheritance, true, NULL
},
{
! "australian_timezones", PGC_USERSET, &Australian_timezones, false, ClearDateCache
},
{
! "fixbtree", PGC_POSTMASTER, &FixBTree, true, NULL
},
{
! "password_encryption", PGC_USERSET, &Password_encryption, false, NULL
},
{
! "transform_null_equals", PGC_USERSET, &Transform_null_equals, false, NULL
},
{
! NULL, 0, NULL, false, NULL
}
};
--- 221,379 ----
ConfigureNamesBool[] =
{
{
! "enable_seqscan", PGC_USERSET, false, &enable_seqscan, NULL, true, NULL
},
{
! "enable_indexscan", PGC_USERSET, false, &enable_indexscan, NULL, true, NULL
},
{
! "enable_tidscan", PGC_USERSET, false, &enable_tidscan, NULL, true, NULL
},
{
! "enable_sort", PGC_USERSET, false, &enable_sort, NULL, true, NULL
},
{
! "enable_nestloop", PGC_USERSET, false, &enable_nestloop, NULL, true, NULL
},
{
! "enable_mergejoin", PGC_USERSET, false, &enable_mergejoin, NULL, true, NULL
},
{
! "enable_hashjoin", PGC_USERSET, false, &enable_hashjoin, NULL, true, NULL
},
{
! "ksqo", PGC_USERSET, false, &_use_keyset_query_optimizer, NULL, false, NULL
},
{
! "geqo", PGC_USERSET, false, &enable_geqo, NULL, true, NULL
},
{
! "tcpip_socket", PGC_POSTMASTER, false, &NetServer, NULL, false, NULL
},
{
! "ssl", PGC_POSTMASTER, false, &EnableSSL, NULL, false, NULL
},
+
{
! "fsync", PGC_SIGHUP, false, &enableFsync, NULL, true, NULL
},
+
{
! "silent_mode", PGC_POSTMASTER, false, &SilentMode, NULL, false, NULL
},
{
! "log_connections", PGC_BACKEND, false, &Log_connections, NULL, false, NULL
},
{
! "log_timestamp", PGC_SIGHUP, false, &Log_timestamp, NULL, false, NULL
},
{
! "log_pid", PGC_SIGHUP, false, &Log_pid, NULL, false, NULL
},
#ifdef USE_ASSERT_CHECKING
{
! "debug_assertions", PGC_USERSET, false, &assert_enabled, NULL, true, NULL
},
#endif
{
! "debug_print_query", PGC_USERSET, false, &Debug_print_query, NULL, false, NULL
},
{
! "debug_print_parse", PGC_USERSET, false, &Debug_print_parse, NULL, false, NULL
},
{
! "debug_print_rewritten", PGC_USERSET, false, &Debug_print_rewritten, NULL, false, NULL
},
{
! "debug_print_plan", PGC_USERSET, false, &Debug_print_plan, NULL, false, NULL
},
{
! "debug_pretty_print", PGC_USERSET, false, &Debug_pretty_print, NULL, false, NULL
},
{
! "show_parser_stats", PGC_USERSET, false, &Show_parser_stats, NULL, false, NULL
},
{
! "show_planner_stats", PGC_USERSET, false, &Show_planner_stats, NULL, false, NULL
},
{
! "show_executor_stats", PGC_USERSET, false, &Show_executor_stats, NULL, false, NULL
},
{
! "show_query_stats", PGC_USERSET, false, &Show_query_stats, NULL, false, NULL
},
#ifdef BTREE_BUILD_STATS
{
! "show_btree_build_stats", PGC_SUSET, false, &Show_btree_build_stats, NULL, false, NULL
},
#endif
{
! "stats_start_collector", PGC_POSTMASTER, false, &pgstat_collect_startcollector, NULL, true, NULL
},
{
! "stats_reset_on_server_start", PGC_POSTMASTER, false, &pgstat_collect_resetonpmstart, NULL, true, NULL
},
{
! "stats_command_string", PGC_SUSET, false, &pgstat_collect_querystring, NULL, false, NULL
},
{
! "stats_row_level", PGC_SUSET, false, &pgstat_collect_tuplelevel, NULL, false, NULL
},
{
! "stats_block_level", PGC_SUSET, false, &pgstat_collect_blocklevel, NULL, false, NULL
},
{
! "trace_notify", PGC_USERSET, false, &Trace_notify, NULL, false, NULL
},
#ifdef LOCK_DEBUG
{
! "trace_locks", PGC_SUSET, false, &Trace_locks, NULL, false, NULL
},
{
! "trace_userlocks", PGC_SUSET, false, &Trace_userlocks, NULL, false, NULL
},
{
! "trace_lwlocks", PGC_SUSET, false, &Trace_lwlocks, NULL, false, NULL
},
{
! "debug_deadlocks", PGC_SUSET, false, &Debug_deadlocks, NULL, false, NULL
},
#endif
{
! "hostname_lookup", PGC_SIGHUP, false, &HostnameLookup, NULL, false, NULL
},
{
! "show_source_port", PGC_SIGHUP, false, &ShowPortNumber, NULL, false, NULL
},
{
! "sql_inheritance", PGC_USERSET, false, &SQL_inheritance, NULL, true, NULL
},
{
! "australian_timezones", PGC_USERSET, false, &Australian_timezones, NULL, false, ClearDateCache
},
{
! "fixbtree", PGC_POSTMASTER, false, &FixBTree, NULL, true, NULL
},
{
! "password_encryption", PGC_USERSET, false, &Password_encryption, NULL, false, NULL
},
{
! "transform_null_equals", PGC_USERSET, false, &Transform_null_equals, NULL, false, NULL
},
{
! NULL, 0, false, NULL, NULL, false, NULL
}
};
***************
*** 352,385 ****
ConfigureNamesInt[] =
{
{
! "geqo_threshold", PGC_USERSET, &geqo_rels,
DEFAULT_GEQO_RELS, 2, INT_MAX, NULL, NULL
},
{
! "geqo_pool_size", PGC_USERSET, &Geqo_pool_size,
DEFAULT_GEQO_POOL_SIZE, 0, MAX_GEQO_POOL_SIZE, NULL, NULL
},
{
! "geqo_effort", PGC_USERSET, &Geqo_effort,
1, 1, INT_MAX, NULL, NULL
},
{
! "geqo_generations", PGC_USERSET, &Geqo_generations,
0, 0, INT_MAX, NULL, NULL
},
{
! "geqo_random_seed", PGC_USERSET, &Geqo_random_seed,
-1, INT_MIN, INT_MAX, NULL, NULL
},
{
! "deadlock_timeout", PGC_POSTMASTER, &DeadlockTimeout,
1000, 0, INT_MAX, NULL, NULL
},
#ifdef ENABLE_SYSLOG
{
! "syslog", PGC_SIGHUP, &Use_syslog,
0, 0, 2, NULL, NULL
},
#endif
--- 382,415 ----
ConfigureNamesInt[] =
{
{
! "geqo_threshold", PGC_USERSET, false, &geqo_rels, NULL,
DEFAULT_GEQO_RELS, 2, INT_MAX, NULL, NULL
},
{
! "geqo_pool_size", PGC_USERSET, false, &Geqo_pool_size, NULL,
DEFAULT_GEQO_POOL_SIZE, 0, MAX_GEQO_POOL_SIZE, NULL, NULL
},
{
! "geqo_effort", PGC_USERSET, false, &Geqo_effort, NULL,
1, 1, INT_MAX, NULL, NULL
},
{
! "geqo_generations", PGC_USERSET, false, &Geqo_generations, NULL,
0, 0, INT_MAX, NULL, NULL
},
{
! "geqo_random_seed", PGC_USERSET, false, &Geqo_random_seed, NULL,
-1, INT_MIN, INT_MAX, NULL, NULL
},
{
! "deadlock_timeout", PGC_POSTMASTER, false, &DeadlockTimeout, NULL,
1000, 0, INT_MAX, NULL, NULL
},
#ifdef ENABLE_SYSLOG
{
! "syslog", PGC_SIGHUP, false, &Use_syslog, NULL,
0, 0, 2, NULL, NULL
},
#endif
***************
*** 390,510 ****
* constraints here are partially unused.
*/
{
! "max_connections", PGC_POSTMASTER, &MaxBackends,
DEF_MAXBACKENDS, 1, INT_MAX, NULL, NULL
},
{
! "shared_buffers", PGC_POSTMASTER, &NBuffers,
DEF_NBUFFERS, 16, INT_MAX, NULL, NULL
},
{
! "port", PGC_POSTMASTER, &PostPortNumber,
DEF_PGPORT, 1, 65535, NULL, NULL
},
{
! "unix_socket_permissions", PGC_POSTMASTER, &Unix_socket_permissions,
0777, 0000, 0777, NULL, NULL
},
{
! "sort_mem", PGC_USERSET, &SortMem,
512, 4 * BLCKSZ / 1024, INT_MAX, NULL, NULL
},
{
! "vacuum_mem", PGC_USERSET, &VacuumMem,
8192, 1024, INT_MAX, NULL, NULL
},
{
! "max_files_per_process", PGC_BACKEND, &max_files_per_process,
1000, 25, INT_MAX, NULL, NULL
},
{
! "debug_level", PGC_USERSET, &DebugLvl,
0, 0, 16, NULL, NULL
},
#ifdef LOCK_DEBUG
{
! "trace_lock_oidmin", PGC_SUSET, &Trace_lock_oidmin,
BootstrapObjectIdData, 1, INT_MAX, NULL, NULL
},
{
! "trace_lock_table", PGC_SUSET, &Trace_lock_table,
0, 0, INT_MAX, NULL, NULL
},
#endif
{
! "max_expr_depth", PGC_USERSET, &max_expr_depth,
DEFAULT_MAX_EXPR_DEPTH, 10, INT_MAX, NULL, NULL
},
{
! "max_fsm_relations", PGC_POSTMASTER, &MaxFSMRelations,
100, 10, INT_MAX, NULL, NULL
},
{
! "max_fsm_pages", PGC_POSTMASTER, &MaxFSMPages,
10000, 1000, INT_MAX, NULL, NULL
},
{
! "max_locks_per_transaction", PGC_POSTMASTER, &max_locks_per_xact,
64, 10, INT_MAX, NULL, NULL
},
{
! "authentication_timeout", PGC_SIGHUP, &AuthenticationTimeout,
60, 1, 600, NULL, NULL
},
{
! "pre_auth_delay", PGC_SIGHUP, &PreAuthDelay,
0, 0, 60, NULL, NULL
},
{
! "checkpoint_segments", PGC_SIGHUP, &CheckPointSegments,
3, 1, INT_MAX, NULL, NULL
},
{
! "checkpoint_timeout", PGC_SIGHUP, &CheckPointTimeout,
300, 30, 3600, NULL, NULL
},
{
! "wal_buffers", PGC_POSTMASTER, &XLOGbuffers,
8, 4, INT_MAX, NULL, NULL
},
{
! "wal_files", PGC_SIGHUP, &XLOGfiles,
0, 0, 64, NULL, NULL
},
{
! "wal_debug", PGC_SUSET, &XLOG_DEBUG,
0, 0, 16, NULL, NULL
},
{
! "commit_delay", PGC_USERSET, &CommitDelay,
0, 0, 100000, NULL, NULL
},
{
! "commit_siblings", PGC_USERSET, &CommitSiblings,
5, 1, 1000, NULL, NULL
},
{
! NULL, 0, NULL, 0, 0, 0, NULL, NULL
}
};
--- 420,540 ----
* constraints here are partially unused.
*/
{
! "max_connections", PGC_POSTMASTER, false, &MaxBackends, NULL,
DEF_MAXBACKENDS, 1, INT_MAX, NULL, NULL
},
{
! "shared_buffers", PGC_POSTMASTER, false, &NBuffers, NULL,
DEF_NBUFFERS, 16, INT_MAX, NULL, NULL
},
{
! "port", PGC_POSTMASTER, false, &PostPortNumber, NULL,
DEF_PGPORT, 1, 65535, NULL, NULL
},
{
! "unix_socket_permissions", PGC_POSTMASTER, false, &Unix_socket_permissions, NULL,
0777, 0000, 0777, NULL, NULL
},
{
! "sort_mem", PGC_USERSET, false, &SortMem, NULL,
512, 4 * BLCKSZ / 1024, INT_MAX, NULL, NULL
},
{
! "vacuum_mem", PGC_USERSET, false, &VacuumMem, NULL,
8192, 1024, INT_MAX, NULL, NULL
},
{
! "max_files_per_process", PGC_BACKEND, false, &max_files_per_process, NULL,
1000, 25, INT_MAX, NULL, NULL
},
{
! "debug_level", PGC_USERSET, false, &DebugLvl, NULL,
0, 0, 16, NULL, NULL
},
#ifdef LOCK_DEBUG
{
! "trace_lock_oidmin", PGC_SUSET, false, &Trace_lock_oidmin, NULL,
BootstrapObjectIdData, 1, INT_MAX, NULL, NULL
},
{
! "trace_lock_table", PGC_SUSET, false, &Trace_lock_table, NULL,
0, 0, INT_MAX, NULL, NULL
},
#endif
{
! "max_expr_depth", PGC_USERSET, false, &max_expr_depth, NULL,
DEFAULT_MAX_EXPR_DEPTH, 10, INT_MAX, NULL, NULL
},
{
! "max_fsm_relations", PGC_POSTMASTER, false, &MaxFSMRelations, NULL,
100, 10, INT_MAX, NULL, NULL
},
{
! "max_fsm_pages", PGC_POSTMASTER, false, &MaxFSMPages, NULL,
10000, 1000, INT_MAX, NULL, NULL
},
{
! "max_locks_per_transaction", PGC_POSTMASTER, false, &max_locks_per_xact, NULL,
64, 10, INT_MAX, NULL, NULL
},
{
! "authentication_timeout", PGC_SIGHUP, false, &AuthenticationTimeout, NULL,
60, 1, 600, NULL, NULL
},
{
! "pre_auth_delay", PGC_SIGHUP, false, &PreAuthDelay, NULL,
0, 0, 60, NULL, NULL
},
{
! "checkpoint_segments", PGC_SIGHUP, false, &CheckPointSegments, NULL,
3, 1, INT_MAX, NULL, NULL
},
{
! "checkpoint_timeout", PGC_SIGHUP, false, &CheckPointTimeout, NULL,
300, 30, 3600, NULL, NULL
},
{
! "wal_buffers", PGC_POSTMASTER, false, &XLOGbuffers, NULL,
8, 4, INT_MAX, NULL, NULL
},
{
! "wal_files", PGC_SIGHUP, false, &XLOGfiles, NULL,
0, 0, 64, NULL, NULL
},
{
! "wal_debug", PGC_SUSET, false, &XLOG_DEBUG, NULL,
0, 0, 16, NULL, NULL
},
{
! "commit_delay", PGC_USERSET, false, &CommitDelay, NULL,
0, 0, 100000, NULL, NULL
},
{
! "commit_siblings", PGC_USERSET, false, &CommitSiblings, NULL,
5, 1, 1000, NULL, NULL
},
{
! NULL, 0, false, NULL, NULL, 0, 0, 0, NULL, NULL
}
};
***************
*** 513,546 ****
ConfigureNamesReal[] =
{
{
! "effective_cache_size", PGC_USERSET, &effective_cache_size,
DEFAULT_EFFECTIVE_CACHE_SIZE, 0, DBL_MAX, NULL, NULL
},
{
! "random_page_cost", PGC_USERSET, &random_page_cost,
DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX, NULL, NULL
},
{
! "cpu_tuple_cost", PGC_USERSET, &cpu_tuple_cost,
DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX, NULL, NULL
},
{
! "cpu_index_tuple_cost", PGC_USERSET, &cpu_index_tuple_cost,
DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX, NULL, NULL
},
{
! "cpu_operator_cost", PGC_USERSET, &cpu_operator_cost,
DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX, NULL, NULL
},
{
! "geqo_selection_bias", PGC_USERSET, &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, NULL
}
};
--- 543,582 ----
ConfigureNamesReal[] =
{
{
! "effective_cache_size", PGC_USERSET, false, &effective_cache_size, NULL,
DEFAULT_EFFECTIVE_CACHE_SIZE, 0, DBL_MAX, NULL, NULL
},
{
! "random_page_cost", PGC_USERSET, false, &random_page_cost, NULL,
DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX, NULL, NULL
},
{
! "cpu_tuple_cost", PGC_USERSET, false, &cpu_tuple_cost, NULL,
DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX, NULL, NULL
},
{
! "cpu_index_tuple_cost", PGC_USERSET, false, &cpu_index_tuple_cost, NULL,
DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX, NULL, NULL
},
{
! "cpu_operator_cost", PGC_USERSET, false, &cpu_operator_cost, NULL,
DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX, NULL, NULL
},
{
! "geqo_selection_bias", PGC_USERSET, false, &Geqo_selection_bias, NULL,
DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS,
MAX_GEQO_SELECTION_BIAS, NULL, NULL
},
+ {
+ "seed", PGC_USERSET, false, &seed, NULL,
+ 0.5, 0, DBL_MAX,
+ NULL, assign_seed
+ },
+
{
! NULL, 0, false, NULL, NULL, 0.0, 0.0, 0.0, NULL, NULL
}
};
***************
*** 549,608 ****
ConfigureNamesString[] =
{
{
! "default_transaction_isolation", PGC_USERSET, &default_iso_level_string,
! "read committed", check_defaultxactisolevel, assign_defaultxactisolevel
},
{
! "dynamic_library_path", PGC_SUSET, &Dynamic_library_path,
! "$libdir", NULL, NULL
},
{
! "krb_server_keyfile", PGC_POSTMASTER, &pg_krb_server_keyfile,
! PG_KRB_SRVTAB, NULL, NULL
},
#ifdef ENABLE_SYSLOG
{
! "syslog_facility", PGC_POSTMASTER, &Syslog_facility,
! "LOCAL0", check_facility, NULL
},
{
! "syslog_ident", PGC_POSTMASTER, &Syslog_ident,
! "postgres", NULL, NULL
},
#endif
{
! "unix_socket_group", PGC_POSTMASTER, &Unix_socket_group,
! "", NULL, NULL
},
{
! "unix_socket_directory", PGC_POSTMASTER, &UnixSocketDir,
! "", NULL, NULL
},
{
! "virtual_host", PGC_POSTMASTER, &VirtualHost,
! "", NULL, NULL
},
{
! "wal_sync_method", PGC_SIGHUP, &XLOG_sync_method,
! XLOG_sync_method_default, check_xlog_sync_method,
! assign_xlog_sync_method
},
{
! NULL, 0, NULL, NULL, NULL, NULL
}
};
/******** end of options list ********/
/*
* Look up option NAME. If it exists, return it's data type, else
--- 585,661 ----
ConfigureNamesString[] =
{
{
! "default_transaction_isolation", PGC_USERSET, false, &default_iso_level_string, NULL,
! "read committed",
! check_defaultxactisolevel, assign_defaultxactisolevel, NULL
},
{
! "dynamic_library_path", PGC_SUSET, false, &Dynamic_library_path, NULL,
! "$libdir", NULL, NULL, NULL
},
{
! "krb_server_keyfile", PGC_POSTMASTER, false, &pg_krb_server_keyfile, NULL,
! PG_KRB_SRVTAB, NULL, NULL, NULL
},
#ifdef ENABLE_SYSLOG
{
! "syslog_facility", PGC_POSTMASTER, false, &Syslog_facility, NULL,
! "LOCAL0", check_facility, NULL, NULL
},
{
! "syslog_ident", PGC_POSTMASTER, false, &Syslog_ident, NULL,
! "postgres", NULL, NULL, NULL
},
#endif
+ {
+ "unix_socket_group", PGC_POSTMASTER, false, &Unix_socket_group, NULL,
+ "", NULL, NULL, NULL
+ },
+
{
! "unix_socket_directory", PGC_POSTMASTER, false, &UnixSocketDir, NULL,
! "", NULL, NULL, NULL
},
{
! "virtual_host", PGC_POSTMASTER, false, &VirtualHost, NULL,
! "", NULL, NULL, NULL
},
{
! "wal_sync_method", PGC_SIGHUP, false, &XLOG_sync_method, NULL,
! XLOG_sync_method_default,
! check_xlog_sync_method, assign_xlog_sync_method, NULL
},
{
! "real_format", PGC_USERSET, false, &Real_format, NULL,
! "%.6g", NULL, NULL, NULL
},
{
! "double_precision_format", PGC_USERSET, false, &Double_precision_format, NULL,
! "%.15g", NULL, NULL, NULL
! },
!
! {
! "server_encoding", PGC_USERSET, true, NULL, display_server_encoding,
! NULL, NULL, NULL, NULL
! },
!
! {
! NULL, 0, false, NULL, NULL, NULL, NULL, NULL, NULL
}
};
/******** end of options list ********/
+ void _ShowOption(enum config_type opttype, struct config_generic * record);
/*
* Look up option NAME. If it exists, return it's data type, else
***************
*** 667,675 ****
--- 720,733 ----
{
struct config_bool *conf = &ConfigureNamesBool[i];
+ if (!isStartup && conf->read_only)
+ continue;
+
if (isStartup ||
conf->context == PGC_SUSET || conf->context == PGC_USERSET)
{
+ if (!conf->variable)
+ continue;
if (conf->assign_hook)
(conf->assign_hook) (conf->default_val);
*conf->variable = conf->default_val;
***************
*** 680,688 ****
--- 738,751 ----
{
struct config_int *conf = &ConfigureNamesInt[i];
+ if (!isStartup && conf->read_only)
+ continue;
+
if (isStartup ||
conf->context == PGC_SUSET || conf->context == PGC_USERSET)
{
+ if (!conf->variable)
+ continue;
if (conf->assign_hook)
(conf->assign_hook) (conf->default_val);
*conf->variable = conf->default_val;
***************
*** 693,701 ****
--- 756,769 ----
{
struct config_real *conf = &ConfigureNamesReal[i];
+ if (!isStartup && conf->read_only)
+ continue;
+
if (isStartup ||
conf->context == PGC_SUSET || conf->context == PGC_USERSET)
{
+ if (!conf->variable)
+ continue;
if (conf->assign_hook)
(conf->assign_hook) (conf->default_val);
*conf->variable = conf->default_val;
***************
*** 706,717 ****
{
struct config_string *conf = &ConfigureNamesString[i];
if (isStartup ||
conf->context == PGC_SUSET || conf->context == PGC_USERSET)
{
char *str = NULL;
! if (conf->default_val == NULL &&
conf->boot_default_val)
{
str = strdup(conf->boot_default_val);
--- 774,790 ----
{
struct config_string *conf = &ConfigureNamesString[i];
+ if (!isStartup && conf->read_only)
+ continue;
+
if (isStartup ||
conf->context == PGC_SUSET || conf->context == PGC_USERSET)
{
char *str = NULL;
! if (!conf->variable)
! continue;
! if (!conf->default_val &&
conf->boot_default_val)
{
str = strdup(conf->boot_default_val);
***************
*** 824,831 ****
return true;
}
-
-
/*
* Try to parse value as a floating point constant in the usual
* format. If the value parsed okay return true, else false. If
--- 897,902 ----
***************
*** 859,864 ****
--- 930,940 ----
* parameter DoIt is false then don't really set the option but do all
* the checks to see if it would work.
*
+ * The reset parameter should be set to true when an explicit SQL
+ * RESET is done. It's purpose is to correctly choose between SET and
+ * RESET when displaying an error message for attempted change of
+ * read-only variables.
+ *
* If there is an error (non-existing option, invalid value) then an
* elog(ERROR) is thrown *unless* this is called as part of the
* configuration file re-read in the SIGHUP handler, in which case we
***************
*** 866,876 ****
* all other cases the function returns true. This is working around
* the deficiencies in the elog mechanism, so don't blame me.
*
* See also SetConfigOption for an external interface.
*/
bool
set_config_option(const char *name, const char *value,
! GucContext context, bool DoIt, bool makeDefault)
{
struct config_generic *record;
enum config_type type;
--- 942,957 ----
* all other cases the function returns true. This is working around
* the deficiencies in the elog mechanism, so don't blame me.
*
+ * elog(DEBUG) is used instead of elug(ERROR) for attempted (re)set of
+ * read-only variables when the context is PGC_POSTMASTER and
+ * PGC_SIGHUP.
+ *
* See also SetConfigOption for an external interface.
*/
bool
set_config_option(const char *name, const char *value,
! GucContext context, bool DoIt,
! bool makeDefault, bool reset)
{
struct config_generic *record;
enum config_type type;
***************
*** 886,891 ****
--- 967,992 ----
}
/*
+ * Read-only variables can't be (re)set.
+ */
+ if (record->read_only)
+ {
+ if (context == PGC_POSTMASTER)
+ elevel = DEBUG;
+
+ if (reset)
+ {
+ elog(elevel, "RESET %s is not supported", name);
+ }
+ else
+ {
+ elog(elevel, "SET %s is not supported", name);
+ }
+
+ return false;
+ }
+
+ /*
* Check if the option can be set at this time. See guc.h for the
* 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.
***************
*** 1145,1249 ****
SetConfigOption(const char *name, const char *value,
GucContext context, bool makeDefault)
{
! (void) set_config_option(name, value, context, true, makeDefault);
}
/*
! * 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
! * elog and don't return.
*
! * The string is *not* allocated for modification and is really only
! * valid until the next call to configuration related functions.
*/
! const char *
! GetConfigOption(const char *name)
{
! struct config_generic *record;
! static char buffer[256];
! enum config_type opttype;
!
! 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_INT:
! snprintf(buffer, sizeof(buffer), "%d",
! *((struct config_int *) record)->variable);
! return buffer;
! case PGC_REAL:
! snprintf(buffer, sizeof(buffer), "%g",
! *((struct config_real *) record)->variable);
! return buffer;
! case PGC_STRING:
! return *((struct config_string *) record)->variable;
! default:
! ;
}
- return NULL;
}
! static void
! _ShowOption(enum config_type opttype, struct config_generic * record)
{
! char buffer[256];
! char *val;
!
! switch (opttype)
! {
! case PGC_BOOL:
! val = *((struct config_bool *) record)->variable ? "on" : "off";
! break;
!
! case PGC_INT:
! snprintf(buffer, sizeof(buffer), "%d",
! *((struct config_int *) record)->variable);
! val = buffer;
! break;
!
! case PGC_REAL:
! snprintf(buffer, sizeof(buffer), "%g",
! *((struct config_real *) record)->variable);
! val = buffer;
! break;
!
! case PGC_STRING:
! val = strlen(*((struct config_string *) record)->variable) != 0 ?
! *((struct config_string *) record)->variable : "unset";
! break;
! default:
! val = "???";
! }
! elog(NOTICE, "%s is %s", record->name, val);
}
void
! ShowAllGUCConfig(void)
{
int i;
for (i = 0; ConfigureNamesBool[i].name; i++)
! _ShowOption(PGC_BOOL, (struct config_generic *) & ConfigureNamesBool[i]);
for (i = 0; ConfigureNamesInt[i].name; i++)
! _ShowOption(PGC_INT, (struct config_generic *) & ConfigureNamesInt[i]);
for (i = 0; ConfigureNamesReal[i].name; i++)
! _ShowOption(PGC_REAL, (struct config_generic *) & ConfigureNamesReal[i]);
for (i = 0; ConfigureNamesString[i].name; i++)
! _ShowOption(PGC_STRING, (struct config_generic *) & ConfigureNamesString[i]);
}
--- 1246,1362 ----
SetConfigOption(const char *name, const char *value,
GucContext context, bool makeDefault)
{
! (void) set_config_option(name, value, context, true, makeDefault, false);
}
+ /*
+ * Reset a config option to its default value. See also set_config_option.
+ */
+ void
+ ResetConfigOption(const char *name, const char *value,
+ GucContext context)
+ {
+ (void) set_config_option(name, value, context, true, false, true);
+ }
+ /*
+ * Check whether or not the given option can be set to the given value.
+ */
+ bool
+ CheckConfigOption(const char *name, const char *value,
+ GucContext context)
+ {
+ return set_config_option(name, value, context, false, false, false);
+ }
/*
! * This is more or less the SHOW command. It elog(NOTICE) to display a
! * string with the value of the option `name'. If the option doesn't
! * exist, throw an elog(ERROR) and don't return.
*
! * See ShowConfigOption and ShowAllOptions for external interfaces.
*/
! void
! show_option(enum config_type opttype, struct config_generic *record)
{
! char buffer[256];
! char *val;
! if (record->display_proc)
{
! (record->display_proc) ();
! }
! else
! {
! switch (opttype)
! {
! case PGC_BOOL:
! val = *((struct config_bool *) record)->variable ? "on" : "off";
! break;
! case PGC_INT:
! snprintf(buffer, sizeof(buffer), "%d",
! *((struct config_int *) record)->variable);
! val = buffer;
! break;
! case PGC_REAL:
! snprintf(buffer, sizeof(buffer), "%g",
! *((struct config_real *) record)->variable);
! val = buffer;
! break;
! case PGC_STRING:
! val = strlen(*((struct config_string *) record)->variable) != 0 ?
! *((struct config_string *) record)->variable : "unset";
! break;
!
! default:
! val = "???";
! }
! elog(NOTICE, "%s is %s", record->name, val);
}
}
! /*
! * SHOW command, basically.
! *
! * See show_option.
! */
! void
! ShowConfigOption(const char *name)
{
! struct config_generic *record;
! enum config_type opttype;
! opttype = find_option(name, &record);
! if (opttype == PGC_NONE)
! elog(ERROR, "Option '%s' is not recognized", name);
! show_option(opttype, record);
}
+ /*
+ * SHOW ALL command, basically.
+ *
+ * See show_option.
+ */
void
! ShowAllOptions(void)
{
int i;
for (i = 0; ConfigureNamesBool[i].name; i++)
! show_option(PGC_BOOL, (struct config_generic *) & ConfigureNamesBool[i]);
for (i = 0; ConfigureNamesInt[i].name; i++)
! show_option(PGC_INT, (struct config_generic *) & ConfigureNamesInt[i]);
for (i = 0; ConfigureNamesReal[i].name; i++)
! show_option(PGC_REAL, (struct config_generic *) & ConfigureNamesReal[i]);
for (i = 0; ConfigureNamesString[i].name; i++)
! show_option(PGC_STRING, (struct config_generic *) & ConfigureNamesString[i]);
}
***************
*** 1324,1334 ****
static bool
check_defaultxactisolevel(const char *value)
{
! return (strcasecmp(value, "read committed") == 0
! || strcasecmp(value, "serializable") == 0)
? true : false;
}
--- 1437,1450 ----
+ /*
+ * Default transaction level
+ */
static bool
check_defaultxactisolevel(const char *value)
{
! return (strcasecmp(value, "read committed") == 0 ||
! strcasecmp(value, "serializable") == 0)
? true : false;
}
***************
*** 1342,1345 ****
--- 1458,1481 ----
DefaultXactIsoLevel = XACT_READ_COMMITTED;
else
elog(ERROR, "bogus transaction isolation level");
+ }
+
+
+ /*
+ * Server encoding
+ */
+ static void
+ display_server_encoding(void)
+ {
+ elog(NOTICE, "server_encoding is '%s'", GetDatabaseEncodingName());
+ }
+
+
+ /*
+ * Seed for random number generator
+ */
+ static void
+ assign_seed(double newval)
+ {
+ DirectFunctionCall1(setseed, Float8GetDatum(newval));
}
Index: src/bin/psql/tab-complete.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/tab-complete.c,v
retrieving revision 1.41
diff -c -r1.41 tab-complete.c
*** src/bin/psql/tab-complete.c 2001/11/05 17:46:31 1.41
--- src/bin/psql/tab-complete.c 2002/01/15 22:20:26
***************
*** 212,219 ****
"DateStyle",
"TimeZone",
"client_encoding",
- "server_encoding",
- "seed",
/*
* the rest should match USERSET entries in
--- 212,217 ----
***************
*** 265,270 ****
--- 263,273 ----
"geqo_selection_bias",
"default_transaction_isolation",
+
+ "real_format",
+ "double_precision_format",
+ "server_encoding",
+ "seed",
NULL
};
Index: src/include/miscadmin.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/miscadmin.h,v
retrieving revision 1.98
diff -c -r1.98 miscadmin.h
*** src/include/miscadmin.h 2002/01/01 23:16:22 1.98
--- src/include/miscadmin.h 2002/01/15 22:20:26
***************
*** 186,191 ****
--- 186,197 ----
extern char *UnixSocketDir;
extern char *VirtualHost;
+ /*
+ * Formatting of real and double precision numbers.
+ */
+
+ extern char *Real_format;
+ extern char *Double_precision_format;
/*****************************************************************************
* pdir.h -- *
Index: src/include/utils/guc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/guc.h,v
retrieving revision 1.13
diff -c -r1.13 guc.h
*** src/include/utils/guc.h 2001/11/05 17:46:36 1.13
--- src/include/utils/guc.h 2002/01/15 22:20:26
***************
61
extern void SetConfigOption(const char *name, const char *value,
! GucContext context, bool makeDefault);
! extern const char *GetConfigOption(const char *name);
extern void ProcessConfigFile(GucContext context);
extern void ResetAllOptions(bool isStartup);
extern void ParseLongOption(const char *string, char **name, char **value);
! 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;
--- 48,63 ----
extern void SetConfigOption(const char *name, const char *value,
! GucContext context, bool makeDefault);
! extern void ResetConfigOption(const char *name, const char *value,
! GucContext context);
! extern bool CheckConfigOption(const char *name, const char *value,
! GucContext context);
! extern void ShowConfigOption(const char *name);
extern void ProcessConfigFile(GucContext context);
extern void ResetAllOptions(bool isStartup);
extern void ParseLongOption(const char *string, char **name, char **value);
! extern void ShowAllOptions(void);
extern bool Debug_print_query;
Liam Stewart writes:
I've removed
GetConfigOption() and replaced it with ShowConfigOption() which does an
elog(NOTICE) instead of returning a string.
I certainly don't like that. I want to be able to get at the
configuration setting without any notice going off.
When setting REAL_FORMAT and DOUBLE_PRECISION_FORMAT, the printf-style
format string should be checked for certain things:
I wouldn't use a printf format string at all. It's not user-friendly --
not everyone is a C programmer, in fact most people aren't. It leaves
open too many ways to shoot yourself in the foot. And if you plan to
close all those ways you end up with a crippled system that is still
complex to understand for many.
What I would like to get out of the configurability of floating-point
numbers is:
1. The ability to dump them in binary or hex format for lossless
dump/reload. (printf("%a") does that.) That could be a boolean
setting.
2. To have (at least as an option) the same output format on all platforms.
Not sure how to approach that, perhaps it has nothing to do with
configurability.
Some people will also suggest
3. Be able to set the number of significant digits that are shown.
to allow simplifying the regression tests, but I do not think that that is
a good idea, because
a. If platforms behave differently, the test suite should not paint over
that; it might be important information.
b. If we actually break floating-point operations one day, we might miss
it.
c. Types represent data, data is altered by functions (round? truncate?).
Global side-effects are evil.
d. Input and output would not be inverses anymore.
--
Peter Eisentraut peter_e@gmx.net
Peter Eisentraut <peter_e@gmx.net> writes:
Liam Stewart writes:
I've removed
GetConfigOption() and replaced it with ShowConfigOption() which does an
elog(NOTICE) instead of returning a string.
I certainly don't like that. I want to be able to get at the
configuration setting without any notice going off.
I agree with Peter --- better to separate the getting of the string
from displaying it. What's the reason for collapsing them together?
When setting REAL_FORMAT and DOUBLE_PRECISION_FORMAT, the printf-style
format string should be checked for certain things:
I wouldn't use a printf format string at all.
Good point. If we have to set up a checking mechanism then we should
ask ourselves why we're bothering to use printf representation.
What I would like to get out of the configurability of floating-point
numbers is:
1. The ability to dump them in binary or hex format for lossless
dump/reload. (printf("%a") does that.)
On some platforms... I'd be happier with this if it were more portable...
Some people will also suggest
3. Be able to set the number of significant digits that are shown.
to allow simplifying the regression tests, but I do not think that that is
a good idea,
[ raises eyebrow ] To my mind that was one of the principal reasons
for working on such a thing at all. If you don't want to allow this,
then what alternative solution do you have for our geometry regression
test mess? (Defining it as not a mess won't fly.)
regards, tom lane
Some people will also suggest
3. Be able to set the number of significant digits that are shown.to allow simplifying the regression tests, but I do not think that that is
a good idea,[ raises eyebrow ] To my mind that was one of the principal reasons
for working on such a thing at all. If you don't want to allow this,
then what alternative solution do you have for our geometry regression
test mess? (Defining it as not a mess won't fly.)
Yes, I doubt the current regression are tests are input/output
reversable because of the rounding anyway.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Tom Lane writes:
[ raises eyebrow ] To my mind that was one of the principal reasons
for working on such a thing at all. If you don't want to allow this,
then what alternative solution do you have for our geometry regression
test mess? (Defining it as not a mess won't fly.)
I did some investigation and noticed that the different geometry expected
files differ in the same 5 groups of places (or less), and in 4 of those
places there are only two possible variations. So that at least gives me
the idea that perhaps the geometry test could be split up in two or three
tests, and that would probably reduce the relative number of "nonstandard"
expected files we'd need.
One difference case is a system failing to implement negative zeros.
Setting the output precision won't fix that.
Actually, I just took a peak into include/utils/geo_decls.h, and the
definiton of EPSILON at the top leaves me to think that printing out
anything more than 6 significant digits is nonsense anyway. Numerical
analysts would probably shudder.
--
Peter Eisentraut peter_e@gmx.net
Peter Eisentraut <peter_e@gmx.net> writes:
Actually, I just took a peak into include/utils/geo_decls.h, and the
definiton of EPSILON at the top leaves me to think that printing out
anything more than 6 significant digits is nonsense anyway. Numerical
analysts would probably shudder.
Indeed. Does that mean you'd be happy with restricting the number of
digits printed for geometrical types only?
regards, tom lane
Tom Lane writes:
Indeed. Does that mean you'd be happy with restricting the number of
digits printed for geometrical types only?
Not really. I'd much rather see the EPSILON removed/revised. I don't
claim to understand numerical analysis, but that thing is completely
bogus. I can see how the error would be controllable when you just add
numbers, but once you start multiplying or run trigonometric functions, a
fixed epsilon just doesn't cut it.
If you want to limit the number of digits, why not just reimplement the
geometric types as single precision?
And if we think that an epsilon-based float comparison is important, why
don't we do it everywhere?
--
Peter Eisentraut peter_e@gmx.net
Peter Eisentraut <peter_e@gmx.net> writes:
Not really. I'd much rather see the EPSILON removed/revised. I don't
claim to understand numerical analysis, but that thing is completely
bogus.
Yeah, and there's even the handy comment:
* XXX These routines were not written by a numerical analyst.
to remind you that this stuff was written by someone who was studying
databases not numerical analysis.
In my eyes, all of our geometric datatypes are firmly in the "academic
toy prototype" category. They could use a thorough overhaul, but in
view of the existence of the PostGIS project I doubt they'll ever get
one. Anyone who might have both the ability and the motivation to
improve these datatypes will probably go use/work on PostGIS instead.
I could make an argument that we should just yank these types from the
distribution and leave the field clear for PostGIS. I don't really want
to take that line; the types do have usefulness for simple applications,
and what's probably more important is they help keep us honest on
datatype extensibility concerns. But I have a hard time justifying
spending any core development time on them.
Basically what I want is some fairly simple answer that will let us stop
wasting quite so much maintenance effort on the geometry regression
test. Because, frankly, that code is nowhere near good enough to
justify our expending much time on it.
In that context, trimming the number of displayed decimal places seems
like a great solution. Whether it's the "right thing" from a purist's
viewpoint doesn't concern me a whole lot.
regards, tom lane
On Thu, Jan 17, 2002 at 05:57:29PM -0500, Tom Lane wrote:
Peter Eisentraut <peter_e@gmx.net> writes:
Liam Stewart writes:
I've removed
GetConfigOption() and replaced it with ShowConfigOption() which does an
elog(NOTICE) instead of returning a string.I certainly don't like that. I want to be able to get at the
configuration setting without any notice going off.I agree with Peter --- better to separate the getting of the string
from displaying it. What's the reason for collapsing them together?
I ended up thinking that GetConfigOption was a bit useless right now
since, with the redone GetPGVariable, there's currently nothing that
would use it. I can see some use for it since not all guc options have
an associated variable but still have a value (e.g.: seed,
server_encoding). How about I add GetConfigOption back in and change
ShowConfigOption to use it. display_proc hooks would return a char *;
GetConfigOption would use a variable's display_proc hook if it is
non-null instead of doing its own thing. ShowConfigOption would no
longer call a variable's display_proc hook.
I wouldn't use a printf format string at all.
Good point. If we have to set up a checking mechanism then we should
ask ourselves why we're bothering to use printf representation.
I was going on the fact that printf format string was on the todo and
that Tom suggested using them last February. When thinking about parsing
printf strings, I realized how not nice it would be, so I'm alright
with a new representation.
What I would like to get out of the configurability of floating-point
numbers is:
1. The ability to dump them in binary or hex format for lossless
dump/reload. (printf("%a") does that.)On some platforms... I'd be happier with this if it were more portable...
Roll our own? %a and %A are C99 so are much less portable than most
other printf conversion specifiers.
Liam
--
Liam Stewart :: Red Hat Canada, Ltd. :: liams@redhat.com
Liam Stewart <liams@redhat.com> writes:
What I would like to get out of the configurability of floating-point
numbers is:
1. The ability to dump them in binary or hex format for lossless
dump/reload. (printf("%a") does that.)On some platforms... I'd be happier with this if it were more portable...
Roll our own? %a and %A are C99 so are much less portable than most
other printf conversion specifiers.
Hmm ... rolling our own might actually not be too unreasonable ...
and the lack of lossless dump/reload for floats has certainly been
a sore point for a long time, so expending some effort here is
justified.
regards, tom lane
Thread has been saved for the 7.3 release:
http://candle.pha.pa.us/cgi-bin/pgpatches2
---------------------------------------------------------------------------
Liam Stewart wrote:
I was playing around with adding a couple new SET commands (REAL_FORMAT
and DOUBLE_PRECISION_FORMAT as per todo list item) and I ended up
playing with GUC a bit.I've cleaned it up a bit - most of the changes should be fairly
self-explanitory from the patch. Some of the configuration options
handled in variable.c (so far, server_encoding and seed) have been moved
into guc.c and are handled by GUC. Moving them in required adding a
couple of fields to config_generic and friends - a read_only field and a
display_proc field (hook for custom SHOW messages). I've removed
GetConfigOption() and replaced it with ShowConfigOption() which does an
elog(NOTICE) instead of returning a string.When setting REAL_FORMAT and DOUBLE_PRECISION_FORMAT, the printf-style
format string should be checked for certain things:- field width of "*" is not allowed
- precision of ".*" is not allowed
- all conversion specifiers except "s" and "n" are allowed
- only one conversion specification other than %% and variations is
allowedDoes this seem reasonable to people? I haven't written a function to
check those yet.. will do soon.This patch isn't complete yet so don't append it to the pending patches
list, Bruce.Liam
--
Liam Stewart :: Red Hat Canada, Ltd. :: liams@redhat.com
[ Attachment, skipping... ]
---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
This patch was rejected. Please continue discussion on the hackers
list.
---------------------------------------------------------------------------
Liam Stewart wrote:
I was playing around with adding a couple new SET commands (REAL_FORMAT
and DOUBLE_PRECISION_FORMAT as per todo list item) and I ended up
playing with GUC a bit.I've cleaned it up a bit - most of the changes should be fairly
self-explanitory from the patch. Some of the configuration options
handled in variable.c (so far, server_encoding and seed) have been moved
into guc.c and are handled by GUC. Moving them in required adding a
couple of fields to config_generic and friends - a read_only field and a
display_proc field (hook for custom SHOW messages). I've removed
GetConfigOption() and replaced it with ShowConfigOption() which does an
elog(NOTICE) instead of returning a string.When setting REAL_FORMAT and DOUBLE_PRECISION_FORMAT, the printf-style
format string should be checked for certain things:- field width of "*" is not allowed
- precision of ".*" is not allowed
- all conversion specifiers except "s" and "n" are allowed
- only one conversion specification other than %% and variations is
allowedDoes this seem reasonable to people? I haven't written a function to
check those yet.. will do soon.This patch isn't complete yet so don't append it to the pending patches
list, Bruce.Liam
--
Liam Stewart :: Red Hat Canada, Ltd. :: liams@redhat.com
[ Attachment, skipping... ]
---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026