2000-05-31 02:28:42 +02:00
|
|
|
/*--------------------------------------------------------------------
|
|
|
|
* guc.c
|
|
|
|
*
|
|
|
|
* Support for grand unified configuration scheme, including SET
|
|
|
|
* command, configuration file, and command line options.
|
2002-05-17 03:19:19 +02:00
|
|
|
* See src/backend/utils/misc/README for more information.
|
2000-05-31 02:28:42 +02:00
|
|
|
*
|
|
|
|
*
|
2008-01-01 20:46:01 +01:00
|
|
|
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
|
2000-05-31 02:28:42 +02:00
|
|
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
2003-04-25 21:45:10 +02:00
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2008-03-10 13:55:13 +01:00
|
|
|
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.437 2008/03/10 12:55:13 mha Exp $
|
2003-04-25 21:45:10 +02:00
|
|
|
*
|
2000-05-31 02:28:42 +02:00
|
|
|
*--------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
#include <ctype.h>
|
2000-05-31 02:28:42 +02:00
|
|
|
#include <float.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <unistd.h>
|
2004-10-08 03:36:36 +02:00
|
|
|
#include <sys/stat.h>
|
2005-10-14 22:53:56 +02:00
|
|
|
#ifdef HAVE_SYSLOG
|
|
|
|
#include <syslog.h>
|
|
|
|
#endif
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2006-07-25 05:51:23 +02:00
|
|
|
#include "access/gin.h"
|
2006-12-13 06:54:48 +01:00
|
|
|
#include "access/transam.h"
|
2005-06-18 00:32:51 +02:00
|
|
|
#include "access/twophase.h"
|
2006-07-13 18:49:20 +02:00
|
|
|
#include "access/xact.h"
|
2002-04-01 05:34:27 +02:00
|
|
|
#include "catalog/namespace.h"
|
2000-05-31 02:28:42 +02:00
|
|
|
#include "commands/async.h"
|
2007-04-12 08:53:49 +02:00
|
|
|
#include "commands/prepare.h"
|
2002-07-31 19:19:54 +02:00
|
|
|
#include "commands/vacuum.h"
|
2006-07-11 19:04:13 +02:00
|
|
|
#include "commands/variable.h"
|
2007-03-20 00:38:32 +01:00
|
|
|
#include "commands/trigger.h"
|
2002-08-15 04:51:27 +02:00
|
|
|
#include "funcapi.h"
|
2000-08-25 12:00:35 +02:00
|
|
|
#include "libpq/auth.h"
|
2003-04-25 21:45:10 +02:00
|
|
|
#include "libpq/pqformat.h"
|
2000-05-31 02:28:42 +02:00
|
|
|
#include "miscadmin.h"
|
|
|
|
#include "optimizer/cost.h"
|
|
|
|
#include "optimizer/geqo.h"
|
|
|
|
#include "optimizer/paths.h"
|
2005-12-20 03:30:36 +01:00
|
|
|
#include "optimizer/planmain.h"
|
2006-05-11 21:15:36 +02:00
|
|
|
#include "parser/gramparse.h"
|
2000-05-31 02:28:42 +02:00
|
|
|
#include "parser/parse_expr.h"
|
2003-06-12 00:13:22 +02:00
|
|
|
#include "parser/parse_relation.h"
|
2006-12-30 22:21:56 +01:00
|
|
|
#include "parser/parse_type.h"
|
2006-02-12 23:32:43 +01:00
|
|
|
#include "parser/scansup.h"
|
2006-07-11 19:04:13 +02:00
|
|
|
#include "pgstat.h"
|
2005-07-14 07:13:45 +02:00
|
|
|
#include "postmaster/autovacuum.h"
|
2004-05-30 00:48:23 +02:00
|
|
|
#include "postmaster/bgwriter.h"
|
|
|
|
#include "postmaster/postmaster.h"
|
2006-07-11 19:04:13 +02:00
|
|
|
#include "postmaster/syslogger.h"
|
2007-07-24 06:54:09 +02:00
|
|
|
#include "postmaster/walwriter.h"
|
2001-09-30 20:57:45 +02:00
|
|
|
#include "storage/fd.h"
|
2001-06-28 01:31:40 +02:00
|
|
|
#include "storage/freespace.h"
|
2000-05-31 02:28:42 +02:00
|
|
|
#include "tcop/tcopprot.h"
|
2007-08-21 03:11:32 +02:00
|
|
|
#include "tsearch/ts_cache.h"
|
2002-03-01 23:45:19 +01:00
|
|
|
#include "utils/builtins.h"
|
2006-07-11 19:04:13 +02:00
|
|
|
#include "utils/guc_tables.h"
|
2004-07-01 02:52:04 +02:00
|
|
|
#include "utils/memutils.h"
|
2002-04-03 07:39:33 +02:00
|
|
|
#include "utils/pg_locale.h"
|
2007-03-20 00:38:32 +01:00
|
|
|
#include "utils/plancache.h"
|
2007-04-12 08:53:49 +02:00
|
|
|
#include "utils/portal.h"
|
2006-06-28 00:16:44 +02:00
|
|
|
#include "utils/ps_status.h"
|
2006-07-25 05:51:23 +02:00
|
|
|
#include "utils/tzparser.h"
|
2007-01-19 17:58:46 +01:00
|
|
|
#include "utils/xml.h"
|
2006-04-25 16:11:59 +02:00
|
|
|
|
2003-04-25 21:45:10 +02:00
|
|
|
#ifndef PG_KRB_SRVTAB
|
|
|
|
#define PG_KRB_SRVTAB ""
|
|
|
|
#endif
|
2005-06-04 22:42:43 +02:00
|
|
|
#ifndef PG_KRB_SRVNAM
|
|
|
|
#define PG_KRB_SRVNAM ""
|
|
|
|
#endif
|
2003-04-25 21:45:10 +02:00
|
|
|
|
2005-10-15 04:49:52 +02:00
|
|
|
#define CONFIG_FILENAME "postgresql.conf"
|
2004-10-10 01:13:22 +02:00
|
|
|
#define HBA_FILENAME "pg_hba.conf"
|
|
|
|
#define IDENT_FILENAME "pg_ident.conf"
|
2004-10-08 03:36:36 +02:00
|
|
|
|
2003-05-03 00:02:47 +02:00
|
|
|
#ifdef EXEC_BACKEND
|
|
|
|
#define CONFIG_EXEC_PARAMS "global/config_exec_params"
|
2005-07-04 06:51:52 +02:00
|
|
|
#define CONFIG_EXEC_PARAMS_NEW "global/config_exec_params.new"
|
2003-05-03 00:02:47 +02:00
|
|
|
#endif
|
2003-04-25 21:45:10 +02:00
|
|
|
|
2005-08-21 01:26:37 +02:00
|
|
|
/* upper limit for GUC variables measured in kilobytes of memory */
|
|
|
|
#if SIZEOF_SIZE_T > 4
|
|
|
|
#define MAX_KILOBYTES INT_MAX
|
|
|
|
#else
|
|
|
|
#define MAX_KILOBYTES (INT_MAX / 1024)
|
|
|
|
#endif
|
|
|
|
|
2006-07-27 10:30:41 +02:00
|
|
|
#define KB_PER_MB (1024)
|
|
|
|
#define KB_PER_GB (1024*1024)
|
|
|
|
|
|
|
|
#define MS_PER_S 1000
|
2007-06-21 20:14:21 +02:00
|
|
|
#define S_PER_MIN 60
|
2006-07-27 10:30:41 +02:00
|
|
|
#define MS_PER_MIN (1000 * 60)
|
2007-06-21 20:14:21 +02:00
|
|
|
#define MIN_PER_H 60
|
|
|
|
#define S_PER_H (60 * 60)
|
2006-07-27 10:30:41 +02:00
|
|
|
#define MS_PER_H (1000 * 60 * 60)
|
2007-06-21 20:14:21 +02:00
|
|
|
#define MIN_PER_D (60 * 24)
|
|
|
|
#define S_PER_D (60 * 60 * 24)
|
2006-07-27 10:30:41 +02:00
|
|
|
#define MS_PER_D (1000 * 60 * 60 * 24)
|
|
|
|
|
2003-04-25 21:45:10 +02:00
|
|
|
/* XXX these should appear in other modules' header files */
|
2004-02-17 04:54:57 +01:00
|
|
|
extern bool Log_disconnections;
|
2001-03-22 05:01:46 +01:00
|
|
|
extern int CommitDelay;
|
|
|
|
extern int CommitSiblings;
|
2004-11-05 20:17:13 +01:00
|
|
|
extern char *default_tablespace;
|
2007-06-03 19:08:34 +02:00
|
|
|
extern char *temp_tablespaces;
|
2008-01-30 19:35:55 +01:00
|
|
|
extern bool synchronize_seqscans;
|
2005-10-15 04:49:52 +02:00
|
|
|
extern bool fullPageWrites;
|
|
|
|
|
2005-10-04 00:55:56 +02:00
|
|
|
#ifdef TRACE_SORT
|
2005-10-15 04:49:52 +02:00
|
|
|
extern bool trace_sort;
|
2005-10-04 00:55:56 +02:00
|
|
|
#endif
|
2007-06-08 20:23:53 +02:00
|
|
|
#ifdef TRACE_SYNCSCAN
|
|
|
|
extern bool trace_syncscan;
|
|
|
|
#endif
|
2007-05-04 03:13:45 +02:00
|
|
|
#ifdef DEBUG_BOUNDED_SORT
|
|
|
|
extern bool optimize_bounded_sort;
|
|
|
|
#endif
|
2001-02-08 00:36:22 +01:00
|
|
|
|
2007-02-16 18:07:00 +01:00
|
|
|
#ifdef USE_SSL
|
|
|
|
extern char *SSLCipherSuites;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2004-04-05 05:02:11 +02:00
|
|
|
static const char *assign_log_destination(const char *value,
|
2004-08-29 07:07:03 +02:00
|
|
|
bool doit, GucSource source);
|
2004-04-05 05:02:11 +02:00
|
|
|
|
2002-04-21 02:22:52 +02:00
|
|
|
#ifdef HAVE_SYSLOG
|
2005-10-14 22:53:56 +02:00
|
|
|
static int syslog_facility = LOG_LOCAL0;
|
2001-07-01 00:03:26 +02:00
|
|
|
|
2005-10-14 22:53:56 +02:00
|
|
|
static const char *assign_syslog_facility(const char *facility,
|
2005-10-15 04:49:52 +02:00
|
|
|
bool doit, GucSource source);
|
2005-10-14 22:53:56 +02:00
|
|
|
static const char *assign_syslog_ident(const char *ident,
|
2005-10-15 04:49:52 +02:00
|
|
|
bool doit, GucSource source);
|
2002-05-17 03:19:19 +02:00
|
|
|
#endif
|
2001-07-01 00:03:26 +02:00
|
|
|
|
> >>1. change the type of "log_statement" option from boolean to string,
> >>with allowed values of "all, mod, ddl, none" with default "none".
OK, here is a patch that implements #1. Here is sample output:
test=> set client_min_messages = 'log';
SET
test=> set log_statement = 'mod';
SET
test=> select 1;
?column?
----------
1
(1 row)
test=> update test set x=1;
LOG: statement: update test set x=1;
ERROR: relation "test" does not exist
test=> update test set x=1;
LOG: statement: update test set x=1;
ERROR: relation "test" does not exist
test=> copy test from '/tmp/x';
LOG: statement: copy test from '/tmp/x';
ERROR: relation "test" does not exist
test=> copy test to '/tmp/x';
ERROR: relation "test" does not exist
test=> prepare xx as select 1;
PREPARE
test=> prepare xx as update x set y=1;
LOG: statement: prepare xx as update x set y=1;
ERROR: relation "x" does not exist
test=> explain analyze select 1;;
QUERY PLAN
------------------------------------------------------------------------------------
Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.006..0.007 rows=1 loops=1)
Total runtime: 0.046 ms
(2 rows)
test=> explain analyze update test set x=1;
LOG: statement: explain analyze update test set x=1;
ERROR: relation "test" does not exist
test=> explain update test set x=1;
ERROR: relation "test" does not exist
It checks PREPARE and EXECUTE ANALYZE too. The log_statement values are
'none', 'mod', 'ddl', and 'all'. For 'all', it prints before the query
is parsed, and for ddl/mod, it does it right after parsing using the
node tag (or command tag for CREATE/ALTER/DROP), so any non-parse errors
will print after the log line.
2004-04-07 07:05:50 +02:00
|
|
|
static const char *assign_defaultxactisolevel(const char *newval, bool doit,
|
|
|
|
GucSource source);
|
2007-03-20 00:38:32 +01:00
|
|
|
static const char *assign_session_replication_role(const char *newval, bool doit,
|
2007-11-15 22:14:46 +01:00
|
|
|
GucSource source);
|
2005-03-20 00:27:11 +01:00
|
|
|
static const char *show_num_temp_buffers(void);
|
2004-01-19 20:04:40 +01:00
|
|
|
static bool assign_phony_autocommit(bool newval, bool doit, GucSource source);
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
static const char *assign_custom_variable_classes(const char *newval, bool doit,
|
2004-08-29 07:07:03 +02:00
|
|
|
GucSource source);
|
2006-01-05 11:07:46 +01:00
|
|
|
static bool assign_debug_assertions(bool newval, bool doit, GucSource source);
|
2005-12-30 01:13:50 +01:00
|
|
|
static bool assign_ssl(bool newval, bool doit, GucSource source);
|
2004-05-07 03:34:08 +02:00
|
|
|
static bool assign_stage_log_stats(bool newval, bool doit, GucSource source);
|
|
|
|
static bool assign_log_stats(bool newval, bool doit, GucSource source);
|
2004-07-01 02:52:04 +02:00
|
|
|
static bool assign_transaction_read_only(bool newval, bool doit, GucSource source);
|
2004-07-11 23:34:04 +02:00
|
|
|
static const char *assign_canonical_path(const char *newval, bool doit, GucSource source);
|
2006-05-21 22:10:42 +02:00
|
|
|
static const char *assign_backslash_quote(const char *newval, bool doit, GucSource source);
|
2006-07-25 05:51:23 +02:00
|
|
|
static const char *assign_timezone_abbreviations(const char *newval, bool doit, GucSource source);
|
2007-01-19 17:58:46 +01:00
|
|
|
static const char *assign_xmlbinary(const char *newval, bool doit, GucSource source);
|
2007-01-25 12:53:52 +01:00
|
|
|
static const char *assign_xmloption(const char *newval, bool doit, GucSource source);
|
2007-09-27 00:36:30 +02:00
|
|
|
static const char *show_archive_command(void);
|
2005-07-30 17:17:26 +02:00
|
|
|
static bool assign_tcp_keepalives_idle(int newval, bool doit, GucSource source);
|
|
|
|
static bool assign_tcp_keepalives_interval(int newval, bool doit, GucSource source);
|
|
|
|
static bool assign_tcp_keepalives_count(int newval, bool doit, GucSource source);
|
|
|
|
static const char *show_tcp_keepalives_idle(void);
|
|
|
|
static const char *show_tcp_keepalives_interval(void);
|
|
|
|
static const char *show_tcp_keepalives_count(void);
|
2007-04-16 20:30:04 +02:00
|
|
|
static bool assign_autovacuum_max_workers(int newval, bool doit, GucSource source);
|
|
|
|
static bool assign_maxconnections(int newval, bool doit, GucSource source);
|
2003-04-25 21:45:10 +02:00
|
|
|
|
2008-03-10 13:55:13 +01:00
|
|
|
/*
|
|
|
|
* Options for enum values defined in this module.
|
|
|
|
*/
|
|
|
|
static const struct config_enum_entry message_level_options[] = {
|
|
|
|
{"debug", DEBUG2},
|
|
|
|
{"debug5", DEBUG5},
|
|
|
|
{"debug4", DEBUG4},
|
|
|
|
{"debug3", DEBUG3},
|
|
|
|
{"debug2", DEBUG2},
|
|
|
|
{"debug1", DEBUG1},
|
|
|
|
{"log", LOG},
|
|
|
|
{"info", INFO},
|
|
|
|
{"notice", NOTICE},
|
|
|
|
{"warning", WARNING},
|
|
|
|
{"error", ERROR},
|
|
|
|
{"fatal", FATAL},
|
|
|
|
{"panic", PANIC},
|
|
|
|
{NULL, 0}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct config_enum_entry log_error_verbosity_options[] = {
|
|
|
|
{"default", PGERROR_DEFAULT},
|
|
|
|
{"terse", PGERROR_TERSE},
|
|
|
|
{"verbose", PGERROR_VERBOSE},
|
|
|
|
{NULL, 0}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct config_enum_entry log_statement_options[] = {
|
|
|
|
{"none", LOGSTMT_NONE},
|
|
|
|
{"ddl", LOGSTMT_DDL},
|
|
|
|
{"mod", LOGSTMT_MOD},
|
|
|
|
{"all", LOGSTMT_ALL},
|
|
|
|
{NULL, 0}
|
|
|
|
};
|
|
|
|
|
2004-10-08 03:36:36 +02:00
|
|
|
/*
|
|
|
|
* GUC option variables that are exported from this module
|
2000-05-31 02:28:42 +02:00
|
|
|
*/
|
2006-01-08 22:24:37 +01:00
|
|
|
#ifdef USE_ASSERT_CHECKING
|
2001-03-22 05:01:46 +01:00
|
|
|
bool assert_enabled = true;
|
2006-01-08 22:24:37 +01:00
|
|
|
#else
|
|
|
|
bool assert_enabled = false;
|
|
|
|
#endif
|
2002-11-15 01:47:22 +01:00
|
|
|
bool log_duration = false;
|
2001-03-22 05:01:46 +01:00
|
|
|
bool Debug_print_plan = false;
|
|
|
|
bool Debug_print_parse = false;
|
|
|
|
bool Debug_print_rewritten = false;
|
|
|
|
bool Debug_pretty_print = false;
|
2003-04-25 21:45:10 +02:00
|
|
|
bool Explain_pretty_print = true;
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-11-15 01:47:22 +01:00
|
|
|
bool log_parser_stats = false;
|
|
|
|
bool log_planner_stats = false;
|
|
|
|
bool log_executor_stats = false;
|
2005-10-15 04:49:52 +02:00
|
|
|
bool log_statement_stats = false; /* this is sort of all three
|
|
|
|
* above together */
|
2002-11-15 02:26:09 +01:00
|
|
|
bool log_btree_build_stats = false;
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2006-10-19 20:32:48 +02:00
|
|
|
bool check_function_bodies = true;
|
|
|
|
bool default_with_oids = false;
|
2001-03-22 05:01:46 +01:00
|
|
|
bool SQL_inheritance = true;
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-08-15 00:07:56 +02:00
|
|
|
bool Password_encryption = true;
|
2001-08-15 20:42:16 +02:00
|
|
|
|
2006-11-21 02:23:37 +01:00
|
|
|
int log_min_error_statement = ERROR;
|
2008-03-10 04:22:29 +01:00
|
|
|
int log_min_messages = WARNING;
|
2002-09-22 21:52:38 +02:00
|
|
|
int client_min_messages = NOTICE;
|
2003-10-08 05:49:38 +02:00
|
|
|
int log_min_duration_statement = -1;
|
2007-01-09 22:31:17 +01:00
|
|
|
int log_temp_files = -1;
|
2003-07-04 18:41:22 +02:00
|
|
|
|
2005-03-20 00:27:11 +01:00
|
|
|
int num_temp_buffers = 1000;
|
|
|
|
|
2004-10-10 01:13:22 +02:00
|
|
|
char *ConfigFileName;
|
|
|
|
char *HbaFileName;
|
|
|
|
char *IdentFileName;
|
|
|
|
char *external_pid_file;
|
2004-10-08 03:36:36 +02:00
|
|
|
|
2005-10-15 04:49:52 +02:00
|
|
|
int tcp_keepalives_idle;
|
|
|
|
int tcp_keepalives_interval;
|
|
|
|
int tcp_keepalives_count;
|
2002-09-02 07:42:54 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
|
|
|
* These variables are all dummies that don't do anything, except in some
|
|
|
|
* cases provide the value for SHOW to display. The real state is elsewhere
|
|
|
|
* and is kept in sync by assign_hooks.
|
|
|
|
*/
|
2004-04-05 05:02:11 +02:00
|
|
|
static char *log_destination_string;
|
2006-10-04 02:30:14 +02:00
|
|
|
|
2006-04-10 23:53:38 +02:00
|
|
|
#ifdef HAVE_SYSLOG
|
2005-10-14 22:53:56 +02:00
|
|
|
static char *syslog_facility_str;
|
|
|
|
static char *syslog_ident_str;
|
2006-04-10 23:53:38 +02:00
|
|
|
#endif
|
2003-05-14 05:26:03 +02:00
|
|
|
static bool phony_autocommit;
|
2003-06-27 21:08:38 +02:00
|
|
|
static bool session_auth_is_superuser;
|
2002-05-17 03:19:19 +02:00
|
|
|
static double phony_random_seed;
|
2006-05-21 22:10:42 +02:00
|
|
|
static char *backslash_quote_string;
|
2002-05-17 03:19:19 +02:00
|
|
|
static char *client_encoding_string;
|
|
|
|
static char *datestyle_string;
|
|
|
|
static char *default_iso_level_string;
|
2007-03-20 00:38:32 +01:00
|
|
|
static char *session_replication_role_string;
|
2003-04-25 21:45:10 +02:00
|
|
|
static char *locale_collate;
|
|
|
|
static char *locale_ctype;
|
2003-02-06 21:25:33 +01:00
|
|
|
static char *regex_flavor_string;
|
2002-05-17 03:19:19 +02:00
|
|
|
static char *server_encoding_string;
|
2003-04-25 21:45:10 +02:00
|
|
|
static char *server_version_string;
|
2006-10-04 02:30:14 +02:00
|
|
|
static int server_version_num;
|
2002-05-17 03:19:19 +02:00
|
|
|
static char *timezone_string;
|
2007-08-04 03:26:54 +02:00
|
|
|
static char *log_timezone_string;
|
2006-07-29 05:02:56 +02:00
|
|
|
static char *timezone_abbreviations_string;
|
2002-05-17 03:19:19 +02:00
|
|
|
static char *XactIsoLevel_string;
|
2004-10-10 01:13:22 +02:00
|
|
|
static char *data_directory;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
static char *custom_variable_classes;
|
2007-01-19 17:58:46 +01:00
|
|
|
static char *xmlbinary_string;
|
2007-01-25 12:53:52 +01:00
|
|
|
static char *xmloption_string;
|
2003-12-03 19:52:00 +01:00
|
|
|
static int max_function_args;
|
|
|
|
static int max_index_keys;
|
|
|
|
static int max_identifier_length;
|
|
|
|
static int block_size;
|
2005-10-15 04:49:52 +02:00
|
|
|
static bool integer_datetimes;
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2005-07-26 00:12:34 +02:00
|
|
|
/* should be static, but commands/variable.c needs to get at these */
|
|
|
|
char *role_string;
|
2004-08-29 07:07:03 +02:00
|
|
|
char *session_authorization_string;
|
2000-08-25 12:00:35 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2003-07-04 18:41:22 +02:00
|
|
|
/*
|
2003-07-28 21:31:32 +02:00
|
|
|
* Displayable names for context types (enum GucContext)
|
|
|
|
*
|
|
|
|
* Note: these strings are deliberately not localized.
|
2003-07-04 18:41:22 +02:00
|
|
|
*/
|
2003-08-04 02:43:34 +02:00
|
|
|
const char *const GucContext_Names[] =
|
2003-07-28 21:31:32 +02:00
|
|
|
{
|
2003-08-04 02:43:34 +02:00
|
|
|
/* PGC_INTERNAL */ "internal",
|
|
|
|
/* PGC_POSTMASTER */ "postmaster",
|
|
|
|
/* PGC_SIGHUP */ "sighup",
|
|
|
|
/* PGC_BACKEND */ "backend",
|
|
|
|
/* PGC_SUSET */ "superuser",
|
|
|
|
/* PGC_USERSET */ "user"
|
2003-07-28 21:31:32 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Displayable names for source types (enum GucSource)
|
|
|
|
*
|
|
|
|
* Note: these strings are deliberately not localized.
|
2003-08-04 02:43:34 +02:00
|
|
|
*/
|
|
|
|
const char *const GucSource_Names[] =
|
2003-07-28 21:31:32 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
/* PGC_S_DEFAULT */ "default",
|
|
|
|
/* PGC_S_ENV_VAR */ "environment variable",
|
|
|
|
/* PGC_S_FILE */ "configuration file",
|
|
|
|
/* PGC_S_ARGV */ "command line",
|
|
|
|
/* PGC_S_DATABASE */ "database",
|
|
|
|
/* PGC_S_USER */ "user",
|
|
|
|
/* PGC_S_CLIENT */ "client",
|
|
|
|
/* PGC_S_OVERRIDE */ "override",
|
|
|
|
/* PGC_S_INTERACTIVE */ "interactive",
|
|
|
|
/* PGC_S_TEST */ "test",
|
|
|
|
/* PGC_S_SESSION */ "session"
|
2003-07-28 21:31:32 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Displayable names for the groupings defined in enum config_group
|
|
|
|
*/
|
|
|
|
const char *const config_group_names[] =
|
|
|
|
{
|
|
|
|
/* UNGROUPED */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Ungrouped"),
|
2004-10-08 03:36:36 +02:00
|
|
|
/* FILE_LOCATIONS */
|
|
|
|
gettext_noop("File Locations"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* CONN_AUTH */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Connections and Authentication"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* CONN_AUTH_SETTINGS */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Connections and Authentication / Connection Settings"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* CONN_AUTH_SECURITY */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Connections and Authentication / Security and Authentication"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* RESOURCES */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Resource Usage"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* RESOURCES_MEM */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Resource Usage / Memory"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* RESOURCES_FSM */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Resource Usage / Free Space Map"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* RESOURCES_KERNEL */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Resource Usage / Kernel Resources"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* WAL */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Write-Ahead Log"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* WAL_SETTINGS */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Write-Ahead Log / Settings"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* WAL_CHECKPOINTS */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Write-Ahead Log / Checkpoints"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* QUERY_TUNING */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Query Tuning"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* QUERY_TUNING_METHOD */
|
2003-12-01 23:08:02 +01:00
|
|
|
gettext_noop("Query Tuning / Planner Method Configuration"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* QUERY_TUNING_COST */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Query Tuning / Planner Cost Constants"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* QUERY_TUNING_GEQO */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Query Tuning / Genetic Query Optimizer"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* QUERY_TUNING_OTHER */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Query Tuning / Other Planner Options"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* LOGGING */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Reporting and Logging"),
|
2004-04-05 05:02:11 +02:00
|
|
|
/* LOGGING_WHERE */
|
|
|
|
gettext_noop("Reporting and Logging / Where to Log"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* LOGGING_WHEN */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Reporting and Logging / When to Log"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* LOGGING_WHAT */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Reporting and Logging / What to Log"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* STATS */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Statistics"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* STATS_MONITORING */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Statistics / Monitoring"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* STATS_COLLECTOR */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Statistics / Query and Index Statistics Collector"),
|
2005-07-14 07:13:45 +02:00
|
|
|
/* AUTOVACUUM */
|
2006-01-05 11:07:46 +01:00
|
|
|
gettext_noop("Autovacuum"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* CLIENT_CONN */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Client Connection Defaults"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* CLIENT_CONN_STATEMENT */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Client Connection Defaults / Statement Behavior"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* CLIENT_CONN_LOCALE */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Client Connection Defaults / Locale and Formatting"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* CLIENT_CONN_OTHER */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Client Connection Defaults / Other Defaults"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* LOCK_MANAGEMENT */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Lock Management"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* COMPAT_OPTIONS */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Version and Platform Compatibility"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* COMPAT_OPTIONS_PREVIOUS */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Version and Platform Compatibility / Previous PostgreSQL Versions"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* COMPAT_OPTIONS_CLIENT */
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Version and Platform Compatibility / Other Platforms and Clients"),
|
2004-10-08 03:36:36 +02:00
|
|
|
/* PRESET_OPTIONS */
|
|
|
|
gettext_noop("Preset Options"),
|
|
|
|
/* CUSTOM_OPTIONS */
|
|
|
|
gettext_noop("Customized Options"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* DEVELOPER_OPTIONS */
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Developer Options"),
|
2003-07-28 21:31:32 +02:00
|
|
|
/* help_config wants this array to be null-terminated */
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2003-07-28 21:31:32 +02:00
|
|
|
/*
|
|
|
|
* Displayable names for GUC variable types (enum config_type)
|
|
|
|
*
|
|
|
|
* Note: these strings are deliberately not localized.
|
|
|
|
*/
|
2003-08-04 02:43:34 +02:00
|
|
|
const char *const config_type_names[] =
|
2003-07-28 21:31:32 +02:00
|
|
|
{
|
2003-08-04 02:43:34 +02:00
|
|
|
/* PGC_BOOL */ "bool",
|
|
|
|
/* PGC_INT */ "integer",
|
|
|
|
/* PGC_REAL */ "real",
|
2008-03-10 13:55:13 +01:00
|
|
|
/* PGC_STRING */ "string",
|
|
|
|
/* PGC_ENUM */ "enum"
|
2003-07-28 21:31:32 +02:00
|
|
|
};
|
|
|
|
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2000-06-23 00:31:24 +02:00
|
|
|
/*
|
2003-07-04 18:41:22 +02:00
|
|
|
* Contents of GUC tables
|
|
|
|
*
|
|
|
|
* See src/backend/utils/misc/README for design notes.
|
|
|
|
*
|
2000-06-23 00:31:24 +02:00
|
|
|
* TO ADD AN OPTION:
|
|
|
|
*
|
|
|
|
* 1. Declare a global variable of type bool, int, double, or char*
|
2004-08-29 07:07:03 +02:00
|
|
|
* and make use of it.
|
2000-06-23 00:31:24 +02:00
|
|
|
*
|
|
|
|
* 2. Decide at what times it's safe to set the option. See guc.h for
|
2004-08-29 07:07:03 +02:00
|
|
|
* details.
|
2000-06-23 00:31:24 +02:00
|
|
|
*
|
|
|
|
* 3. Decide on a name, a default value, upper and lower bounds (if
|
2004-08-29 07:07:03 +02:00
|
|
|
* applicable), etc.
|
2000-06-23 00:31:24 +02:00
|
|
|
*
|
|
|
|
* 4. Add a record below.
|
|
|
|
*
|
2004-01-06 18:26:23 +01:00
|
|
|
* 5. Add it to src/backend/utils/misc/postgresql.conf.sample, if
|
2007-09-11 02:06:42 +02:00
|
|
|
* appropriate.
|
2001-01-24 19:37:31 +01:00
|
|
|
*
|
2007-09-11 02:06:42 +02:00
|
|
|
* 6. Don't forget to document the option (at least in config.sgml).
|
2001-01-24 19:37:31 +01:00
|
|
|
*
|
2007-06-18 12:02:57 +02:00
|
|
|
* 7. If it's a new GUC_LIST option you must edit pg_dumpall.c to ensure
|
2004-08-29 07:07:03 +02:00
|
|
|
* it is not single quoted at dump time.
|
2000-06-23 00:31:24 +02:00
|
|
|
*/
|
|
|
|
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/******** option records follow ********/
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2003-07-04 18:41:22 +02:00
|
|
|
static struct config_bool ConfigureNamesBool[] =
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables the planner's use of sequential-scan plans."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&enable_seqscan,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2001-10-28 07:26:15 +01:00
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"enable_indexscan", PGC_USERSET, QUERY_TUNING_METHOD,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables the planner's use of index-scan plans."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&enable_indexscan,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2005-04-21 21:18:13 +02:00
|
|
|
{
|
|
|
|
{"enable_bitmapscan", PGC_USERSET, QUERY_TUNING_METHOD,
|
|
|
|
gettext_noop("Enables the planner's use of bitmap-scan plans."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&enable_bitmapscan,
|
|
|
|
true, NULL, NULL
|
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"enable_tidscan", PGC_USERSET, QUERY_TUNING_METHOD,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables the planner's use of TID scan plans."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&enable_tidscan,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"enable_sort", PGC_USERSET, QUERY_TUNING_METHOD,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables the planner's use of explicit sort steps."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&enable_sort,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2002-11-21 01:42:20 +01:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"enable_hashagg", PGC_USERSET, QUERY_TUNING_METHOD,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables the planner's use of hashed aggregation plans."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&enable_hashagg,
|
2002-11-21 01:42:20 +01:00
|
|
|
true, NULL, NULL
|
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"enable_nestloop", PGC_USERSET, QUERY_TUNING_METHOD,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables the planner's use of nested-loop join plans."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&enable_nestloop,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"enable_mergejoin", PGC_USERSET, QUERY_TUNING_METHOD,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables the planner's use of merge join plans."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&enable_mergejoin,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"enable_hashjoin", PGC_USERSET, QUERY_TUNING_METHOD,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables the planner's use of hash join plans."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&enable_hashjoin,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2005-07-23 23:05:48 +02:00
|
|
|
{
|
2005-08-22 19:35:03 +02:00
|
|
|
{"constraint_exclusion", PGC_USERSET, QUERY_TUNING_OTHER,
|
2005-11-05 00:50:30 +01:00
|
|
|
gettext_noop("Enables the planner to use constraints to optimize queries."),
|
|
|
|
gettext_noop("Child table scans will be skipped if their "
|
2005-11-22 19:17:34 +01:00
|
|
|
"constraints guarantee that no rows match the query.")
|
2005-07-23 23:05:48 +02:00
|
|
|
},
|
2005-08-22 19:35:03 +02:00
|
|
|
&constraint_exclusion,
|
2005-07-23 23:05:48 +02:00
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"geqo", PGC_USERSET, QUERY_TUNING_GEQO,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables genetic query optimization."),
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("This algorithm attempts to do planning without "
|
2003-10-19 00:59:09 +02:00
|
|
|
"exhaustive searching.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&enable_geqo,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2003-06-27 21:08:38 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
/* Not for general use --- used by SET SESSION AUTHORIZATION */
|
|
|
|
{"is_superuser", PGC_INTERNAL, UNGROUPED,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Shows whether the current user is a superuser."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
2003-06-27 21:08:38 +02:00
|
|
|
&session_auth_is_superuser,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"ssl", PGC_POSTMASTER, CONN_AUTH_SECURITY,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables SSL connections."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&EnableSSL,
|
2005-12-30 01:13:50 +01:00
|
|
|
false, assign_ssl, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"fsync", PGC_SIGHUP, WAL_SETTINGS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Forces synchronization of updates to disk."),
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("The server will use the fsync() system call in several places to make "
|
2005-11-22 19:17:34 +01:00
|
|
|
"sure that updates are physically written to disk. This insures "
|
2003-07-04 18:41:22 +02:00
|
|
|
"that a database cluster will recover to a consistent state after "
|
2003-09-25 08:58:07 +02:00
|
|
|
"an operating system or hardware crash.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&enableFsync,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2007-08-02 00:45:09 +02:00
|
|
|
{
|
|
|
|
{"synchronous_commit", PGC_USERSET, WAL_SETTINGS,
|
|
|
|
gettext_noop("Sets immediate fsync at commit."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&XactSyncCommit,
|
2007-09-10 04:01:19 +02:00
|
|
|
true, NULL, NULL
|
2007-08-02 00:45:09 +02:00
|
|
|
},
|
2003-03-28 21:17:13 +01:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"zero_damaged_pages", PGC_SUSET, DEVELOPER_OPTIONS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Continues processing past damaged page headers."),
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Detection of a damaged page header normally causes PostgreSQL to "
|
2005-10-15 04:49:52 +02:00
|
|
|
"report an error, aborting the current transaction. Setting "
|
2003-07-04 18:41:22 +02:00
|
|
|
"zero_damaged_pages to true causes the system to instead report a "
|
|
|
|
"warning, zero out the damaged page, and continue processing. This "
|
2003-09-25 08:58:07 +02:00
|
|
|
"behavior will destroy data, namely all the rows on the damaged page."),
|
2003-11-07 22:27:38 +01:00
|
|
|
GUC_NOT_IN_SAMPLE
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&zero_damaged_pages,
|
2003-03-28 21:17:13 +01:00
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2005-07-06 01:18:10 +02:00
|
|
|
{
|
|
|
|
{"full_page_writes", PGC_SIGHUP, WAL_SETTINGS,
|
|
|
|
gettext_noop("Writes full pages to WAL when first modified after a checkpoint."),
|
|
|
|
gettext_noop("A page write in process during an operating system crash might be "
|
2005-10-16 20:26:00 +02:00
|
|
|
"only partially written to disk. During recovery, the row changes "
|
2005-11-22 19:17:34 +01:00
|
|
|
"stored in WAL are not enough to recover. This option writes "
|
2005-07-06 01:18:10 +02:00
|
|
|
"pages when first modified after a checkpoint to WAL so full recovery "
|
|
|
|
"is possible.")
|
|
|
|
},
|
|
|
|
&fullPageWrites,
|
|
|
|
true, NULL, NULL
|
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"silent_mode", PGC_POSTMASTER, LOGGING_WHEN,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Runs the server silently."),
|
2003-09-29 02:05:25 +02:00
|
|
|
gettext_noop("If this parameter is set, the server will automatically run in the "
|
2005-10-15 04:49:52 +02:00
|
|
|
"background and any controlling terminals are dissociated.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&SilentMode,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2007-06-30 21:12:02 +02:00
|
|
|
{
|
|
|
|
{"log_checkpoints", PGC_SIGHUP, LOGGING_WHAT,
|
|
|
|
gettext_noop("Logs each checkpoint."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&log_checkpoints,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"log_connections", PGC_BACKEND, LOGGING_WHAT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Logs each successful connection."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&Log_connections,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2004-02-17 04:54:57 +01:00
|
|
|
{
|
|
|
|
{"log_disconnections", PGC_BACKEND, LOGGING_WHAT,
|
2004-10-12 23:54:45 +02:00
|
|
|
gettext_noop("Logs end of a session, including duration."),
|
2004-08-29 07:07:03 +02:00
|
|
|
NULL
|
2004-02-17 04:54:57 +01:00
|
|
|
},
|
|
|
|
&Log_disconnections,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"debug_assertions", PGC_USERSET, DEVELOPER_OPTIONS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Turns on various assertion checks."),
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("This is a debugging aid."),
|
2003-07-04 18:41:22 +02:00
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&assert_enabled,
|
2006-01-05 11:07:46 +01:00
|
|
|
#ifdef USE_ASSERT_CHECKING
|
|
|
|
true,
|
|
|
|
#else
|
|
|
|
false,
|
2000-07-12 19:38:53 +02:00
|
|
|
#endif
|
2006-01-05 11:07:46 +01:00
|
|
|
assign_debug_assertions, NULL
|
|
|
|
},
|
2003-05-28 20:19:09 +02:00
|
|
|
{
|
|
|
|
/* currently undocumented, so don't show in SHOW ALL */
|
2003-07-04 18:41:22 +02:00
|
|
|
{"exit_on_error", PGC_USERSET, UNGROUPED,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("No description available."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&ExitOnAnyError,
|
2003-05-28 20:19:09 +02:00
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2002-09-02 01:26:06 +02:00
|
|
|
{
|
2004-11-14 20:35:35 +01:00
|
|
|
{"log_duration", PGC_SUSET, LOGGING_WHAT,
|
|
|
|
gettext_noop("Logs the duration of each completed SQL statement."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&log_duration,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"debug_print_parse", PGC_USERSET, LOGGING_WHAT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Prints the parse tree to the server log."),
|
2003-09-25 08:58:07 +02:00
|
|
|
NULL
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&Debug_print_parse,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"debug_print_rewritten", PGC_USERSET, LOGGING_WHAT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Prints the parse tree after rewriting to server log."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&Debug_print_rewritten,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"debug_print_plan", PGC_USERSET, LOGGING_WHAT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Prints the execution plan to server log."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&Debug_print_plan,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"debug_pretty_print", PGC_USERSET, LOGGING_WHAT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Indents parse and plan tree displays."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&Debug_pretty_print,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2004-11-14 20:35:35 +01:00
|
|
|
{"log_parser_stats", PGC_SUSET, STATS_MONITORING,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Writes parser performance statistics to the server log."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&log_parser_stats,
|
2004-05-07 03:34:08 +02:00
|
|
|
false, assign_stage_log_stats, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2004-11-14 20:35:35 +01:00
|
|
|
{"log_planner_stats", PGC_SUSET, STATS_MONITORING,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Writes planner performance statistics to the server log."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&log_planner_stats,
|
2004-05-07 03:34:08 +02:00
|
|
|
false, assign_stage_log_stats, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2004-11-14 20:35:35 +01:00
|
|
|
{"log_executor_stats", PGC_SUSET, STATS_MONITORING,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Writes executor performance statistics to the server log."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&log_executor_stats,
|
2004-05-07 03:34:08 +02:00
|
|
|
false, assign_stage_log_stats, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2004-11-14 20:35:35 +01:00
|
|
|
{"log_statement_stats", PGC_SUSET, STATS_MONITORING,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Writes cumulative performance statistics to the server log."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&log_statement_stats,
|
2004-05-07 03:34:08 +02:00
|
|
|
false, assign_log_stats, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-05-31 02:28:42 +02:00
|
|
|
#ifdef BTREE_BUILD_STATS
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"log_btree_build_stats", PGC_SUSET, DEVELOPER_OPTIONS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("No description available."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&log_btree_build_stats,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-05-31 02:28:42 +02:00
|
|
|
#endif
|
|
|
|
|
2002-03-24 05:31:09 +01:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"explain_pretty_print", PGC_USERSET, CLIENT_CONN_OTHER,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Uses the indented output format for EXPLAIN VERBOSE."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&Explain_pretty_print,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2002-03-24 05:31:09 +01:00
|
|
|
},
|
2007-09-24 05:12:23 +02:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2007-09-24 05:12:23 +02:00
|
|
|
{"track_activities", PGC_SUSET, STATS_COLLECTOR,
|
|
|
|
gettext_noop("Collects information about executing commands."),
|
|
|
|
gettext_noop("Enables the collection of information on the currently "
|
|
|
|
"executing command of each session, along with "
|
|
|
|
"the time at which that command began execution.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
2007-09-24 05:12:23 +02:00
|
|
|
&pgstat_track_activities,
|
2007-01-16 19:26:02 +01:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2007-09-24 05:12:23 +02:00
|
|
|
{"track_counts", PGC_SUSET, STATS_COLLECTOR,
|
|
|
|
gettext_noop("Collects statistics on database activity."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
2007-09-24 05:12:23 +02:00
|
|
|
&pgstat_track_counts,
|
2006-06-27 21:07:50 +02:00
|
|
|
true, NULL, NULL
|
2006-06-19 03:51:22 +02:00
|
|
|
},
|
|
|
|
|
2006-06-28 00:16:44 +02:00
|
|
|
{
|
|
|
|
{"update_process_title", PGC_SUSET, STATS_COLLECTOR,
|
|
|
|
gettext_noop("Updates the process title to show the active SQL command."),
|
2006-06-28 01:25:28 +02:00
|
|
|
gettext_noop("Enables updating of the process title every time a new SQL command is received by the server.")
|
2006-06-28 00:16:44 +02:00
|
|
|
},
|
|
|
|
&update_process_title,
|
|
|
|
true, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2005-07-14 07:13:45 +02:00
|
|
|
{
|
|
|
|
{"autovacuum", PGC_SIGHUP, AUTOVACUUM,
|
2005-10-29 02:31:52 +02:00
|
|
|
gettext_noop("Starts the autovacuum subprocess."),
|
2005-07-14 07:13:45 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&autovacuum_start_daemon,
|
2007-01-16 19:26:02 +01:00
|
|
|
true, NULL, NULL
|
2005-07-14 07:13:45 +02:00
|
|
|
},
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"trace_notify", PGC_USERSET, DEVELOPER_OPTIONS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Generates debugging output for LISTEN and NOTIFY."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&Trace_notify,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-05-31 02:28:42 +02:00
|
|
|
|
|
|
|
#ifdef LOCK_DEBUG
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"trace_locks", PGC_SUSET, DEVELOPER_OPTIONS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("No description available."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&Trace_locks,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"trace_userlocks", PGC_SUSET, DEVELOPER_OPTIONS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("No description available."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&Trace_userlocks,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"trace_lwlocks", PGC_SUSET, DEVELOPER_OPTIONS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("No description available."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&Trace_lwlocks,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"debug_deadlocks", PGC_SUSET, DEVELOPER_OPTIONS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("No description available."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&Debug_deadlocks,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-05-31 02:28:42 +02:00
|
|
|
#endif
|
|
|
|
|
2007-03-03 19:46:40 +01:00
|
|
|
{
|
2007-06-19 22:13:22 +02:00
|
|
|
{"log_lock_waits", PGC_SUSET, LOGGING_WHAT,
|
|
|
|
gettext_noop("Logs long lock waits."),
|
2007-03-03 19:46:40 +01:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&log_lock_waits,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2007-06-19 22:13:22 +02:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"log_hostname", PGC_SIGHUP, LOGGING_WHAT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Logs the host name in the connection logs."),
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("By default, connection logs only show the IP address "
|
|
|
|
"of the connecting host. If you want them to show the host name you "
|
2005-10-15 04:49:52 +02:00
|
|
|
"can turn this on, but depending on your host name resolution "
|
|
|
|
"setup it might impose a non-negligible performance penalty.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&log_hostname,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"sql_inheritance", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Causes subtables to be included by default in various commands."),
|
2003-09-25 08:58:07 +02:00
|
|
|
NULL
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&SQL_inheritance,
|
2002-05-17 03:19:19 +02:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"password_encryption", PGC_USERSET, CONN_AUTH_SECURITY,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Encrypt passwords."),
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("When a password is specified in CREATE USER or "
|
2005-10-15 04:49:52 +02:00
|
|
|
"ALTER USER without writing either ENCRYPTED or UNENCRYPTED, "
|
2003-09-29 02:05:25 +02:00
|
|
|
"this parameter determines whether the password is to be encrypted.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&Password_encryption,
|
2002-08-15 01:02:59 +02:00
|
|
|
true, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"transform_null_equals", PGC_USERSET, COMPAT_OPTIONS_CLIENT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Treats \"expr=NULL\" as \"expr IS NULL\"."),
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("When turned on, expressions of the form expr = NULL "
|
2005-10-15 04:49:52 +02:00
|
|
|
"(or NULL = expr) are treated as expr IS NULL, that is, they "
|
|
|
|
"return true if expr evaluates to the null value, and false "
|
|
|
|
"otherwise. The correct behavior of expr = NULL is to always "
|
2003-09-25 08:58:07 +02:00
|
|
|
"return null (unknown).")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&Transform_null_equals,
|
2002-05-17 03:19:19 +02:00
|
|
|
false, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2002-08-18 05:03:26 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"db_user_namespace", PGC_SIGHUP, CONN_AUTH_SECURITY,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Enables per-database user names."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&Db_user_namespace,
|
2002-08-18 05:03:26 +02:00
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2002-08-31 00:18:07 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
/* only here for backwards compatibility */
|
|
|
|
{"autocommit", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("This parameter doesn't do anything."),
|
|
|
|
gettext_noop("It's just here so that we won't choke on SET AUTOCOMMIT TO ON from 7.3-vintage clients."),
|
2003-07-04 18:41:22 +02:00
|
|
|
GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&phony_autocommit,
|
2003-05-14 05:26:03 +02:00
|
|
|
true, assign_phony_autocommit, NULL
|
2002-08-31 00:18:07 +02:00
|
|
|
},
|
2003-01-10 23:03:30 +01:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"default_transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the default read-only status of new transactions."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&DefaultXactReadOnly,
|
2003-01-10 23:03:30 +01:00
|
|
|
false, NULL, NULL
|
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
2003-12-01 04:55:21 +01:00
|
|
|
gettext_noop("Sets the current transaction's read-only status."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
|
|
|
&XactReadOnly,
|
2004-07-01 02:52:04 +02:00
|
|
|
false, assign_transaction_read_only, NULL
|
2003-01-10 23:03:30 +01:00
|
|
|
},
|
2003-06-12 00:13:22 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"add_missing_from", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Automatically adds missing table references to FROM clauses."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&add_missing_from,
|
2005-04-08 02:59:59 +02:00
|
|
|
false, NULL, NULL
|
2003-06-12 00:13:22 +02:00
|
|
|
},
|
2003-10-03 21:26:49 +02:00
|
|
|
{
|
|
|
|
{"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Check function bodies during CREATE FUNCTION."),
|
2003-10-03 21:26:49 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&check_function_bodies,
|
|
|
|
true, NULL, NULL
|
|
|
|
},
|
2005-11-17 23:14:56 +01:00
|
|
|
{
|
|
|
|
{"array_nulls", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
|
|
|
|
gettext_noop("Enable input of NULL elements in arrays."),
|
|
|
|
gettext_noop("When turned on, unquoted NULL in an array input "
|
2006-10-06 19:14:01 +02:00
|
|
|
"value means a null value; "
|
2005-11-17 23:14:56 +01:00
|
|
|
"otherwise it is taken literally.")
|
|
|
|
},
|
|
|
|
&Array_nulls,
|
|
|
|
true, NULL, NULL
|
|
|
|
},
|
2003-12-01 23:08:02 +01:00
|
|
|
{
|
|
|
|
{"default_with_oids", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
|
2005-03-13 10:36:31 +01:00
|
|
|
gettext_noop("Create new tables with OIDs by default."),
|
2004-08-29 07:07:03 +02:00
|
|
|
NULL
|
2003-12-01 23:08:02 +01:00
|
|
|
},
|
|
|
|
&default_with_oids,
|
2005-03-13 10:36:31 +01:00
|
|
|
false, NULL, NULL
|
2003-12-01 23:08:02 +01:00
|
|
|
},
|
2003-12-03 19:52:00 +01:00
|
|
|
{
|
2007-08-19 03:41:25 +02:00
|
|
|
{"logging_collector", PGC_POSTMASTER, LOGGING_WHERE,
|
|
|
|
gettext_noop("Start a subprocess to capture stderr output and/or csvlogs into log files."),
|
2004-08-29 07:07:03 +02:00
|
|
|
NULL
|
2003-12-03 19:52:00 +01:00
|
|
|
},
|
2007-08-19 03:41:25 +02:00
|
|
|
&Logging_collector,
|
2003-12-03 19:52:00 +01:00
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2004-08-31 06:53:44 +02:00
|
|
|
{
|
|
|
|
{"log_truncate_on_rotation", PGC_SIGHUP, LOGGING_WHERE,
|
2004-10-12 23:54:45 +02:00
|
|
|
gettext_noop("Truncate existing log files of same name during log rotation."),
|
2004-08-31 06:53:44 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&Log_truncate_on_rotation,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2003-12-03 19:52:00 +01:00
|
|
|
|
2005-10-04 00:55:56 +02:00
|
|
|
#ifdef TRACE_SORT
|
|
|
|
{
|
|
|
|
{"trace_sort", PGC_USERSET, DEVELOPER_OPTIONS,
|
|
|
|
gettext_noop("Emit information about resource usage in sorting."),
|
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&trace_sort,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
|
2007-06-08 20:23:53 +02:00
|
|
|
#ifdef TRACE_SYNCSCAN
|
|
|
|
/* this is undocumented because not exposed in a standard build */
|
|
|
|
{
|
|
|
|
{"trace_syncscan", PGC_USERSET, DEVELOPER_OPTIONS,
|
|
|
|
gettext_noop("Generate debugging output for synchronized scanning."),
|
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&trace_syncscan,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
|
2007-05-04 03:13:45 +02:00
|
|
|
#ifdef DEBUG_BOUNDED_SORT
|
|
|
|
/* this is undocumented because not exposed in a standard build */
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"optimize_bounded_sort", PGC_USERSET, QUERY_TUNING_METHOD,
|
|
|
|
gettext_noop("Enable bounded sorting using heap sort."),
|
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&optimize_bounded_sort,
|
|
|
|
true, NULL, NULL
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
|
2004-01-06 18:26:23 +01:00
|
|
|
#ifdef WAL_DEBUG
|
|
|
|
{
|
|
|
|
{"wal_debug", PGC_SUSET, DEVELOPER_OPTIONS,
|
|
|
|
gettext_noop("Emit WAL-related debugging output."),
|
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&XLOG_DEBUG,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
|
2004-08-06 01:32:13 +02:00
|
|
|
{
|
2004-10-08 03:36:36 +02:00
|
|
|
{"integer_datetimes", PGC_INTERNAL, PRESET_OPTIONS,
|
2005-10-08 22:08:19 +02:00
|
|
|
gettext_noop("Datetimes are integer based."),
|
2004-08-06 01:32:13 +02:00
|
|
|
NULL,
|
2004-08-16 04:12:29 +02:00
|
|
|
GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
2004-08-06 01:32:13 +02:00
|
|
|
},
|
|
|
|
&integer_datetimes,
|
|
|
|
#ifdef HAVE_INT64_TIMESTAMP
|
|
|
|
true, NULL, NULL
|
|
|
|
#else
|
|
|
|
false, NULL, NULL
|
|
|
|
#endif
|
|
|
|
},
|
|
|
|
|
2005-06-04 22:42:43 +02:00
|
|
|
{
|
|
|
|
{"krb_caseins_users", PGC_POSTMASTER, CONN_AUTH_SECURITY,
|
2007-07-10 15:14:22 +02:00
|
|
|
gettext_noop("Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive."),
|
2005-06-04 22:42:43 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&pg_krb_caseins_users,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2005-06-26 05:04:37 +02:00
|
|
|
{
|
|
|
|
{"escape_string_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
|
2005-06-26 21:16:07 +02:00
|
|
|
gettext_noop("Warn about backslash escapes in ordinary string literals."),
|
2005-06-26 05:04:37 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&escape_string_warning,
|
2006-03-07 03:54:23 +01:00
|
|
|
true, NULL, NULL
|
2005-06-26 05:04:37 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2006-03-06 20:49:20 +01:00
|
|
|
{"standard_conforming_strings", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Causes '...' strings to treat backslashes literally."),
|
2005-06-26 05:04:37 +02:00
|
|
|
NULL,
|
2006-03-06 20:49:20 +01:00
|
|
|
GUC_REPORT
|
2005-06-26 05:04:37 +02:00
|
|
|
},
|
2005-08-15 00:19:50 +02:00
|
|
|
&standard_conforming_strings,
|
2005-06-26 05:04:37 +02:00
|
|
|
false, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2008-01-30 19:35:55 +01:00
|
|
|
{
|
|
|
|
{"synchronize_seqscans", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
|
|
|
|
gettext_noop("Enable synchronized sequential scans."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&synchronize_seqscans,
|
|
|
|
true, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
{
|
|
|
|
{"archive_mode", PGC_POSTMASTER, WAL_SETTINGS,
|
|
|
|
gettext_noop("Allows archiving of WAL files using archive_command."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&XLogArchiveMode,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
2007-09-27 00:36:30 +02:00
|
|
|
|
2006-01-05 11:07:46 +01:00
|
|
|
{
|
2006-01-09 11:05:31 +01:00
|
|
|
{"allow_system_table_mods", PGC_POSTMASTER, DEVELOPER_OPTIONS,
|
2006-10-04 02:30:14 +02:00
|
|
|
gettext_noop("Allows modifications of the structure of system tables."),
|
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
2006-01-05 11:07:46 +01:00
|
|
|
},
|
|
|
|
&allowSystemTableMods,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"ignore_system_indexes", PGC_BACKEND, DEVELOPER_OPTIONS,
|
2006-10-04 02:30:14 +02:00
|
|
|
gettext_noop("Disables reading from system indexes."),
|
|
|
|
gettext_noop("It does not prevent updating the indexes, so it is safe "
|
|
|
|
"to use. The worst consequence is slowness."),
|
|
|
|
GUC_NOT_IN_SAMPLE
|
2006-01-05 11:07:46 +01:00
|
|
|
},
|
|
|
|
&IgnoreSystemIndexes,
|
|
|
|
false, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2003-06-12 00:13:22 +02:00
|
|
|
/* End-of-list marker */
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL
|
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2003-07-04 18:41:22 +02:00
|
|
|
static struct config_int ConfigureNamesInt[] =
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2006-08-18 01:04:10 +02:00
|
|
|
{
|
|
|
|
{"archive_timeout", PGC_SIGHUP, WAL_SETTINGS,
|
2006-10-04 02:30:14 +02:00
|
|
|
gettext_noop("Forces a switch to the next xlog file if a "
|
|
|
|
"new file has not been started within N seconds."),
|
|
|
|
NULL,
|
|
|
|
GUC_UNIT_S
|
2006-08-18 01:04:10 +02:00
|
|
|
},
|
|
|
|
&XLogArchiveTimeout,
|
|
|
|
0, 0, INT_MAX, NULL, NULL
|
|
|
|
},
|
2006-01-05 11:07:46 +01:00
|
|
|
{
|
|
|
|
{"post_auth_delay", PGC_BACKEND, DEVELOPER_OPTIONS,
|
2006-10-04 02:30:14 +02:00
|
|
|
gettext_noop("Waits N seconds on connection startup after authentication."),
|
|
|
|
gettext_noop("This allows attaching a debugger to the process."),
|
|
|
|
GUC_NOT_IN_SAMPLE | GUC_UNIT_S
|
2006-01-05 11:07:46 +01:00
|
|
|
},
|
|
|
|
&PostAuthDelay,
|
|
|
|
0, 0, INT_MAX, NULL, NULL
|
|
|
|
},
|
2002-07-31 19:19:54 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"default_statistics_target", PGC_USERSET, QUERY_TUNING_OTHER,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the default statistics target."),
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("This applies to table columns that have not had a "
|
2005-10-15 04:49:52 +02:00
|
|
|
"column-specific target set via ALTER TABLE SET STATISTICS.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&default_statistics_target,
|
2002-07-31 19:19:54 +02:00
|
|
|
10, 1, 1000, NULL, NULL
|
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"from_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Sets the FROM-list size beyond which subqueries "
|
|
|
|
"are not collapsed."),
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("The planner will merge subqueries into upper "
|
2005-10-15 04:49:52 +02:00
|
|
|
"queries if the resulting FROM list would have no more than "
|
2003-09-25 08:58:07 +02:00
|
|
|
"this many items.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&from_collapse_limit,
|
2003-01-26 00:10:30 +01:00
|
|
|
8, 1, INT_MAX, NULL, NULL
|
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"join_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Sets the FROM-list size beyond which JOIN "
|
|
|
|
"constructs are not flattened."),
|
2005-12-20 03:30:36 +01:00
|
|
|
gettext_noop("The planner will flatten explicit JOIN "
|
2006-12-06 18:35:49 +01:00
|
|
|
"constructs into lists of FROM items whenever a "
|
|
|
|
"list of no more than this many items would result.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&join_collapse_limit,
|
2003-01-26 00:10:30 +01:00
|
|
|
8, 1, INT_MAX, NULL, NULL
|
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"geqo_threshold", PGC_USERSET, QUERY_TUNING_GEQO,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the threshold of FROM items beyond which GEQO is used."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&geqo_threshold,
|
2004-01-24 00:54:21 +01:00
|
|
|
12, 2, INT_MAX, NULL, NULL
|
2001-10-28 07:26:15 +01:00
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2004-01-24 00:54:21 +01:00
|
|
|
{"geqo_effort", PGC_USERSET, QUERY_TUNING_GEQO,
|
|
|
|
gettext_noop("GEQO: effort is used to set the default for other GEQO parameters."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
2004-01-24 00:54:21 +01:00
|
|
|
&Geqo_effort,
|
|
|
|
DEFAULT_GEQO_EFFORT, MIN_GEQO_EFFORT, MAX_GEQO_EFFORT, NULL, NULL
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{"geqo_pool_size", PGC_USERSET, QUERY_TUNING_GEQO,
|
|
|
|
gettext_noop("GEQO: number of individuals in the population."),
|
|
|
|
gettext_noop("Zero selects a suitable default value.")
|
|
|
|
},
|
2003-07-04 18:41:22 +02:00
|
|
|
&Geqo_pool_size,
|
2004-01-24 00:54:21 +01:00
|
|
|
0, 0, INT_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"geqo_generations", PGC_USERSET, QUERY_TUNING_GEQO,
|
2004-01-22 00:33:34 +01:00
|
|
|
gettext_noop("GEQO: number of iterations of the algorithm."),
|
2004-01-24 00:54:21 +01:00
|
|
|
gettext_noop("Zero selects a suitable default value.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&Geqo_generations,
|
2001-10-30 06:38:56 +01:00
|
|
|
0, 0, INT_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"deadlock_timeout", PGC_SIGHUP, LOCK_MANAGEMENT,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Sets the time to wait on a lock before checking for deadlock."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_MS
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&DeadlockTimeout,
|
2007-11-15 22:14:46 +01:00
|
|
|
1000, 1, INT_MAX / 1000, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-05-31 02:28:42 +02:00
|
|
|
|
|
|
|
/*
|
2008-03-09 05:56:28 +01:00
|
|
|
* Note: MaxBackends is limited to INT_MAX/4 because some places compute
|
|
|
|
* 4*MaxBackends without any overflow check. This check is made in
|
2007-11-15 22:14:46 +01:00
|
|
|
* assign_maxconnections, since MaxBackends is computed as MaxConnections
|
2008-03-09 05:56:28 +01:00
|
|
|
* plus autovacuum_max_workers.
|
2007-04-16 20:30:04 +02:00
|
|
|
*
|
|
|
|
* Likewise we have to limit NBuffers to INT_MAX/2.
|
2000-05-31 02:28:42 +02:00
|
|
|
*/
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"max_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the maximum number of concurrent connections."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
2007-04-16 20:30:04 +02:00
|
|
|
&MaxConnections,
|
|
|
|
100, 1, INT_MAX / 4, assign_maxconnections, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-06-28 01:31:40 +02:00
|
|
|
|
2002-08-29 23:02:12 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"superuser_reserved_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the number of connection slots reserved for superusers."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&ReservedBackends,
|
2006-09-03 01:04:20 +02:00
|
|
|
3, 0, INT_MAX / 4, NULL, NULL
|
2002-08-29 23:02:12 +02:00
|
|
|
},
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"shared_buffers", PGC_POSTMASTER, RESOURCES_MEM,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the number of shared memory buffers used by the server."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_BLOCKS
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&NBuffers,
|
2006-10-03 23:11:55 +02:00
|
|
|
1024, 16, INT_MAX / 2, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-06-28 01:31:40 +02:00
|
|
|
|
2005-03-20 00:27:11 +01:00
|
|
|
{
|
|
|
|
{"temp_buffers", PGC_USERSET, RESOURCES_MEM,
|
|
|
|
gettext_noop("Sets the maximum number of temporary buffers used by each session."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_BLOCKS
|
2005-03-20 00:27:11 +01:00
|
|
|
},
|
|
|
|
&num_temp_buffers,
|
2006-10-03 23:11:55 +02:00
|
|
|
1024, 100, INT_MAX / 2, NULL, show_num_temp_buffers
|
2005-03-20 00:27:11 +01:00
|
|
|
},
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"port", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the TCP port the server listens on."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&PostPortNumber,
|
2001-10-30 06:38:56 +01:00
|
|
|
DEF_PGPORT, 1, 65535, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"unix_socket_permissions", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the access permissions of the Unix-domain socket."),
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Unix-domain sockets use the usual Unix file system "
|
2003-09-29 02:05:25 +02:00
|
|
|
"permission set. The parameter value is expected to be an numeric mode "
|
2003-07-28 02:09:16 +02:00
|
|
|
"specification in the form accepted by the chmod and umask system "
|
2003-07-04 18:41:22 +02:00
|
|
|
"calls. (To use the customary octal format the number must start with "
|
|
|
|
"a 0 (zero).)")
|
|
|
|
},
|
|
|
|
&Unix_socket_permissions,
|
2001-10-30 06:38:56 +01:00
|
|
|
0777, 0000, 0777, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-06-28 01:31:40 +02:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2004-02-03 18:34:04 +01:00
|
|
|
{"work_mem", PGC_USERSET, RESOURCES_MEM,
|
|
|
|
gettext_noop("Sets the maximum memory to be used for query workspaces."),
|
Wording cleanup for error messages. Also change can't -> cannot.
Standard English uses "may", "can", and "might" in different ways:
may - permission, "You may borrow my rake."
can - ability, "I can lift that log."
might - possibility, "It might rain today."
Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice. Similarly, "It may crash" is better stated, "It might crash".
2007-02-01 20:10:30 +01:00
|
|
|
gettext_noop("This much memory can be used by each internal "
|
2005-10-15 04:49:52 +02:00
|
|
|
"sort operation and hash table before switching to "
|
2006-07-27 10:30:41 +02:00
|
|
|
"temporary disk files."),
|
|
|
|
GUC_UNIT_KB
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
2004-02-03 18:34:04 +01:00
|
|
|
&work_mem,
|
2005-08-21 01:26:37 +02:00
|
|
|
1024, 8 * BLCKSZ / 1024, MAX_KILOBYTES, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2004-02-03 18:34:04 +01:00
|
|
|
{"maintenance_work_mem", PGC_USERSET, RESOURCES_MEM,
|
|
|
|
gettext_noop("Sets the maximum memory to be used for maintenance operations."),
|
2006-07-27 10:30:41 +02:00
|
|
|
gettext_noop("This includes operations such as VACUUM and CREATE INDEX."),
|
|
|
|
GUC_UNIT_KB
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
2004-02-03 18:34:04 +01:00
|
|
|
&maintenance_work_mem,
|
2005-08-21 01:26:37 +02:00
|
|
|
16384, 1024, MAX_KILOBYTES, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-09-21 05:32:36 +02:00
|
|
|
|
2004-03-24 23:40:29 +01:00
|
|
|
{
|
|
|
|
{"max_stack_depth", PGC_SUSET, RESOURCES_MEM,
|
|
|
|
gettext_noop("Sets the maximum stack depth, in kilobytes."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_KB
|
2004-03-24 23:40:29 +01:00
|
|
|
},
|
|
|
|
&max_stack_depth,
|
2006-10-07 21:25:29 +02:00
|
|
|
100, 100, MAX_KILOBYTES, assign_max_stack_depth, NULL
|
2004-03-24 23:40:29 +01:00
|
|
|
},
|
|
|
|
|
2004-02-06 20:36:18 +01:00
|
|
|
{
|
|
|
|
{"vacuum_cost_page_hit", PGC_USERSET, RESOURCES,
|
|
|
|
gettext_noop("Vacuum cost for a page found in the buffer cache."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&VacuumCostPageHit,
|
|
|
|
1, 0, 10000, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"vacuum_cost_page_miss", PGC_USERSET, RESOURCES,
|
|
|
|
gettext_noop("Vacuum cost for a page not found in the buffer cache."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&VacuumCostPageMiss,
|
|
|
|
10, 0, 10000, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"vacuum_cost_page_dirty", PGC_USERSET, RESOURCES,
|
|
|
|
gettext_noop("Vacuum cost for a page dirtied by vacuum."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&VacuumCostPageDirty,
|
|
|
|
20, 0, 10000, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"vacuum_cost_limit", PGC_USERSET, RESOURCES,
|
|
|
|
gettext_noop("Vacuum cost amount available before napping."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&VacuumCostLimit,
|
|
|
|
200, 1, 10000, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2004-08-06 06:15:09 +02:00
|
|
|
{"vacuum_cost_delay", PGC_USERSET, RESOURCES,
|
|
|
|
gettext_noop("Vacuum cost delay in milliseconds."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_MS
|
2004-02-06 20:36:18 +01:00
|
|
|
},
|
2004-08-06 06:15:09 +02:00
|
|
|
&VacuumCostDelay,
|
2004-08-08 17:37:06 +02:00
|
|
|
0, 0, 1000, NULL, NULL
|
2004-02-06 20:36:18 +01:00
|
|
|
},
|
|
|
|
|
2005-08-11 23:11:50 +02:00
|
|
|
{
|
|
|
|
{"autovacuum_vacuum_cost_delay", PGC_SIGHUP, AUTOVACUUM,
|
|
|
|
gettext_noop("Vacuum cost delay in milliseconds, for autovacuum."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_MS
|
2005-08-11 23:11:50 +02:00
|
|
|
},
|
|
|
|
&autovacuum_vac_cost_delay,
|
2007-07-24 03:53:56 +02:00
|
|
|
20, -1, 1000, NULL, NULL
|
2005-08-11 23:11:50 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"autovacuum_vacuum_cost_limit", PGC_SIGHUP, AUTOVACUUM,
|
|
|
|
gettext_noop("Vacuum cost amount available before napping, for autovacuum."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&autovacuum_vac_cost_limit,
|
|
|
|
-1, -1, 10000, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2004-02-23 21:45:59 +01:00
|
|
|
{"max_files_per_process", PGC_POSTMASTER, RESOURCES_KERNEL,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the maximum number of simultaneously open files for each server process."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&max_files_per_process,
|
2001-10-30 06:38:56 +01:00
|
|
|
1000, 25, INT_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-09-30 20:57:45 +02:00
|
|
|
|
2005-06-18 00:32:51 +02:00
|
|
|
{
|
|
|
|
{"max_prepared_transactions", PGC_POSTMASTER, RESOURCES,
|
|
|
|
gettext_noop("Sets the maximum number of simultaneously prepared transactions."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&max_prepared_xacts,
|
2005-08-29 23:38:18 +02:00
|
|
|
5, 0, INT_MAX, NULL, NULL
|
2005-06-18 00:32:51 +02:00
|
|
|
},
|
|
|
|
|
2000-05-31 02:28:42 +02:00
|
|
|
#ifdef LOCK_DEBUG
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"trace_lock_oidmin", PGC_SUSET, DEVELOPER_OPTIONS,
|
2007-02-14 04:08:44 +01:00
|
|
|
gettext_noop("No description available."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&Trace_lock_oidmin,
|
2005-04-13 20:54:57 +02:00
|
|
|
FirstNormalObjectId, 0, INT_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"trace_lock_table", PGC_SUSET, DEVELOPER_OPTIONS,
|
2007-02-14 04:08:44 +01:00
|
|
|
gettext_noop("No description available."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE
|
|
|
|
},
|
|
|
|
&Trace_lock_table,
|
2001-10-30 06:38:56 +01:00
|
|
|
0, 0, INT_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-05-31 02:28:42 +02:00
|
|
|
#endif
|
|
|
|
|
2002-07-13 03:02:14 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"statement_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Sets the maximum allowed duration of any statement."),
|
2006-07-27 10:30:41 +02:00
|
|
|
gettext_noop("A value of 0 turns off the timeout."),
|
|
|
|
GUC_UNIT_MS
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&StatementTimeout,
|
2002-07-13 03:02:14 +02:00
|
|
|
0, 0, INT_MAX, NULL, NULL
|
|
|
|
},
|
|
|
|
|
Fix recently-understood problems with handling of XID freezing, particularly
in PITR scenarios. We now WAL-log the replacement of old XIDs with
FrozenTransactionId, so that such replacement is guaranteed to propagate to
PITR slave databases. Also, rather than relying on hint-bit updates to be
preserved, pg_clog is not truncated until all instances of an XID are known to
have been replaced by FrozenTransactionId. Add new GUC variables and
pg_autovacuum columns to allow management of the freezing policy, so that
users can trade off the size of pg_clog against the amount of freezing work
done. Revise the already-existing code that forces autovacuum of tables
approaching the wraparound point to make it more bulletproof; also, revise the
autovacuum logic so that anti-wraparound vacuuming is done per-table rather
than per-database. initdb forced because of changes in pg_class, pg_database,
and pg_autovacuum catalogs. Heikki Linnakangas, Simon Riggs, and Tom Lane.
2006-11-05 23:42:10 +01:00
|
|
|
{
|
|
|
|
{"vacuum_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
|
|
|
gettext_noop("Minimum age at which VACUUM should freeze a table row."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&vacuum_freeze_min_age,
|
|
|
|
100000000, 0, 1000000000, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"max_fsm_relations", PGC_POSTMASTER, RESOURCES_FSM,
|
2004-10-16 21:08:38 +02:00
|
|
|
gettext_noop("Sets the maximum number of tables and indexes for which free space is tracked."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&MaxFSMRelations,
|
2003-03-04 22:51:22 +01:00
|
|
|
1000, 100, INT_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"max_fsm_pages", PGC_POSTMASTER, RESOURCES_FSM,
|
2004-10-16 21:08:38 +02:00
|
|
|
gettext_noop("Sets the maximum number of disk pages for which free space is tracked."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&MaxFSMPages,
|
2003-03-04 22:51:22 +01:00
|
|
|
20000, 1000, INT_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-06-28 01:31:40 +02:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"max_locks_per_transaction", PGC_POSTMASTER, LOCK_MANAGEMENT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the maximum number of locks per transaction."),
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("The shared lock table is sized on the assumption that "
|
2005-10-15 04:49:52 +02:00
|
|
|
"at most max_locks_per_transaction * max_connections distinct "
|
2004-10-16 21:08:38 +02:00
|
|
|
"objects will need to be locked at any one time.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&max_locks_per_xact,
|
2001-10-30 06:38:56 +01:00
|
|
|
64, 10, INT_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-11-01 22:14:03 +01:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"authentication_timeout", PGC_SIGHUP, CONN_AUTH_SECURITY,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Sets the maximum allowed time to complete client authentication."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_S
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&AuthenticationTimeout,
|
2001-10-30 06:38:56 +01:00
|
|
|
60, 1, 600, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-09-21 19:06:12 +02:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
/* Not for general use */
|
|
|
|
{"pre_auth_delay", PGC_SIGHUP, DEVELOPER_OPTIONS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Waits N seconds on connection startup before authentication."),
|
|
|
|
gettext_noop("This allows attaching a debugger to the process."),
|
2006-07-27 10:30:41 +02:00
|
|
|
GUC_NOT_IN_SAMPLE | GUC_UNIT_S
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&PreAuthDelay,
|
2001-10-30 06:38:56 +01:00
|
|
|
0, 0, 60, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-09-21 19:06:12 +02:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"checkpoint_segments", PGC_SIGHUP, WAL_CHECKPOINTS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the maximum distance in log segments between automatic WAL checkpoints."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&CheckPointSegments,
|
2001-10-30 06:38:56 +01:00
|
|
|
3, 1, INT_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
XLOG (and related) changes:
* Store two past checkpoint locations, not just one, in pg_control.
On startup, we fall back to the older checkpoint if the newer one
is unreadable. Also, a physical copy of the newest checkpoint record
is kept in pg_control for possible use in disaster recovery (ie,
complete loss of pg_xlog). Also add a version number for pg_control
itself. Remove archdir from pg_control; it ought to be a GUC
parameter, not a special case (not that it's implemented yet anyway).
* Suppress successive checkpoint records when nothing has been entered
in the WAL log since the last one. This is not so much to avoid I/O
as to make it actually useful to keep track of the last two
checkpoints. If the things are right next to each other then there's
not a lot of redundancy gained...
* Change CRC scheme to a true 64-bit CRC, not a pair of 32-bit CRCs
on alternate bytes. Polynomial borrowed from ECMA DLT1 standard.
* Fix XLOG record length handling so that it will work at BLCKSZ = 32k.
* Change XID allocation to work more like OID allocation. (This is of
dubious necessity, but I think it's a good idea anyway.)
* Fix a number of minor bugs, such as off-by-one logic for XLOG file
wraparound at the 4 gig mark.
* Add documentation and clean up some coding infelicities; move file
format declarations out to include files where planned contrib
utilities can get at them.
* Checkpoint will now occur every CHECKPOINT_SEGMENTS log segments or
every CHECKPOINT_TIMEOUT seconds, whichever comes first. It is also
possible to force a checkpoint by sending SIGUSR1 to the postmaster
(undocumented feature...)
* Defend against kill -9 postmaster by storing shmem block's key and ID
in postmaster.pid lockfile, and checking at startup to ensure that no
processes are still connected to old shmem block (if it still exists).
* Switch backends to accept SIGQUIT rather than SIGUSR1 for emergency
stop, for symmetry with postmaster and xlog utilities. Clean up signal
handling in bootstrap.c so that xlog utilities launched by postmaster
will react to signals better.
* Standalone bootstrap now grabs lockfile in target directory, as added
insurance against running it in parallel with live postmaster.
2001-03-13 02:17:06 +01:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"checkpoint_timeout", PGC_SIGHUP, WAL_CHECKPOINTS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Sets the maximum time between automatic WAL checkpoints."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_S
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&CheckPointTimeout,
|
2001-10-30 06:38:56 +01:00
|
|
|
300, 30, 3600, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-11-09 12:26:00 +01:00
|
|
|
|
2002-11-15 03:44:57 +01:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"checkpoint_warning", PGC_SIGHUP, WAL_CHECKPOINTS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Enables warnings if checkpoint segments are filled more "
|
|
|
|
"frequently than this."),
|
2003-09-29 02:05:25 +02:00
|
|
|
gettext_noop("Write a message to the server log if checkpoints "
|
2005-10-15 04:49:52 +02:00
|
|
|
"caused by the filling of checkpoint segment files happens more "
|
2006-09-22 19:41:21 +02:00
|
|
|
"frequently than this number of seconds. Zero turns off the warning."),
|
|
|
|
GUC_UNIT_S
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&CheckPointWarning,
|
2002-11-15 03:44:57 +01:00
|
|
|
30, 0, INT_MAX, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"wal_buffers", PGC_POSTMASTER, WAL_SETTINGS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the number of disk-page buffers in shared memory for WAL."),
|
2006-10-03 23:11:55 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_XBLOCKS
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&XLOGbuffers,
|
2005-08-21 01:26:37 +02:00
|
|
|
8, 4, INT_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-11-09 12:26:00 +01:00
|
|
|
|
2007-07-24 06:54:09 +02:00
|
|
|
{
|
|
|
|
{"wal_writer_delay", PGC_SIGHUP, WAL_SETTINGS,
|
|
|
|
gettext_noop("WAL writer sleep time between WAL flushes."),
|
|
|
|
NULL,
|
|
|
|
GUC_UNIT_MS
|
|
|
|
},
|
|
|
|
&WalWriterDelay,
|
|
|
|
200, 1, 10000, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2007-08-02 00:45:09 +02:00
|
|
|
{"commit_delay", PGC_USERSET, WAL_SETTINGS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the delay in microseconds between transaction commit and "
|
|
|
|
"flushing WAL to disk."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&CommitDelay,
|
2001-10-30 06:38:56 +01:00
|
|
|
0, 0, 100000, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-11-30 02:47:33 +01:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2007-08-02 00:45:09 +02:00
|
|
|
{"commit_siblings", PGC_USERSET, WAL_SETTINGS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the minimum concurrent open transactions before performing "
|
|
|
|
"commit_delay."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&CommitSiblings,
|
2001-10-30 06:38:56 +01:00
|
|
|
5, 1, 1000, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-02-26 01:50:08 +01:00
|
|
|
|
2002-11-08 18:37:52 +01:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"extra_float_digits", PGC_USERSET, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the number of digits displayed for floating-point values."),
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("This affects real, double precision, and geometric data types. "
|
2005-10-15 04:49:52 +02:00
|
|
|
"The parameter value is added to the standard number of digits "
|
2003-09-25 08:58:07 +02:00
|
|
|
"(FLT_DIG or DBL_DIG as appropriate).")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&extra_float_digits,
|
2002-11-08 18:37:52 +01:00
|
|
|
0, -15, 2, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2003-06-11 20:01:14 +02:00
|
|
|
{
|
2004-11-14 20:35:35 +01:00
|
|
|
{"log_min_duration_statement", PGC_SUSET, LOGGING_WHEN,
|
2007-09-24 05:12:23 +02:00
|
|
|
gettext_noop("Sets the minimum execution time above which "
|
|
|
|
"statements will be logged."),
|
|
|
|
gettext_noop("Zero prints all queries. -1 turns this feature off."),
|
2006-07-27 10:30:41 +02:00
|
|
|
GUC_UNIT_MS
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&log_min_duration_statement,
|
2003-10-08 05:49:38 +02:00
|
|
|
-1, -1, INT_MAX / 1000, NULL, NULL
|
2003-06-11 20:01:14 +02:00
|
|
|
},
|
|
|
|
|
2007-04-18 18:44:18 +02:00
|
|
|
{
|
2007-09-24 05:12:23 +02:00
|
|
|
{"log_autovacuum_min_duration", PGC_SIGHUP, LOGGING_WHAT,
|
|
|
|
gettext_noop("Sets the minimum execution time above which "
|
|
|
|
"autovacuum actions will be logged."),
|
|
|
|
gettext_noop("Zero prints all actions. -1 turns autovacuum logging off."),
|
2007-04-18 18:44:18 +02:00
|
|
|
GUC_UNIT_MS
|
|
|
|
},
|
2007-09-24 05:12:23 +02:00
|
|
|
&Log_autovacuum_min_duration,
|
2007-04-18 18:44:18 +02:00
|
|
|
-1, -1, INT_MAX / 1000, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2003-11-19 16:55:08 +01:00
|
|
|
{
|
|
|
|
{"bgwriter_delay", PGC_SIGHUP, RESOURCES,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Background writer sleep time between rounds."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_MS
|
2003-11-19 16:55:08 +01:00
|
|
|
},
|
|
|
|
&BgWriterDelay,
|
2004-10-18 00:01:51 +02:00
|
|
|
200, 10, 10000, NULL, NULL
|
2003-11-19 16:55:08 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2005-03-04 21:21:07 +01:00
|
|
|
{"bgwriter_lru_maxpages", PGC_SIGHUP, RESOURCES,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Background writer maximum number of LRU pages to flush per round."),
|
2003-11-19 16:55:08 +01:00
|
|
|
NULL
|
|
|
|
},
|
2005-03-04 21:21:07 +01:00
|
|
|
&bgwriter_lru_maxpages,
|
2007-09-25 22:03:38 +02:00
|
|
|
100, 0, 1000, NULL, NULL
|
2003-11-19 16:55:08 +01:00
|
|
|
},
|
|
|
|
|
2004-08-06 01:32:13 +02:00
|
|
|
{
|
|
|
|
{"log_rotation_age", PGC_SIGHUP, LOGGING_WHERE,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Automatic log file rotation will occur after N minutes."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_MIN
|
2004-08-06 01:32:13 +02:00
|
|
|
},
|
|
|
|
&Log_RotationAge,
|
2005-07-21 20:06:13 +02:00
|
|
|
HOURS_PER_DAY * MINS_PER_HOUR, 0, INT_MAX / MINS_PER_HOUR, NULL, NULL
|
2004-08-06 01:32:13 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"log_rotation_size", PGC_SIGHUP, LOGGING_WHERE,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Automatic log file rotation will occur after N kilobytes."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_KB
|
2004-08-06 01:32:13 +02:00
|
|
|
},
|
|
|
|
&Log_RotationSize,
|
2004-10-16 21:08:38 +02:00
|
|
|
10 * 1024, 0, INT_MAX / 1024, NULL, NULL
|
2004-08-06 01:32:13 +02:00
|
|
|
},
|
|
|
|
|
2003-12-03 19:52:00 +01:00
|
|
|
{
|
2004-10-08 03:36:36 +02:00
|
|
|
{"max_function_args", PGC_INTERNAL, PRESET_OPTIONS,
|
2004-10-12 23:54:45 +02:00
|
|
|
gettext_noop("Shows the maximum number of function arguments."),
|
2003-12-03 19:52:00 +01:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
|
|
|
&max_function_args,
|
|
|
|
FUNC_MAX_ARGS, FUNC_MAX_ARGS, FUNC_MAX_ARGS, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2004-10-08 03:36:36 +02:00
|
|
|
{"max_index_keys", PGC_INTERNAL, PRESET_OPTIONS,
|
2004-10-12 23:54:45 +02:00
|
|
|
gettext_noop("Shows the maximum number of index keys."),
|
2003-12-03 19:52:00 +01:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
|
|
|
&max_index_keys,
|
|
|
|
INDEX_MAX_KEYS, INDEX_MAX_KEYS, INDEX_MAX_KEYS, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2004-10-08 03:36:36 +02:00
|
|
|
{"max_identifier_length", PGC_INTERNAL, PRESET_OPTIONS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Shows the maximum identifier length."),
|
2003-12-03 19:52:00 +01:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
|
|
|
&max_identifier_length,
|
|
|
|
NAMEDATALEN - 1, NAMEDATALEN - 1, NAMEDATALEN - 1, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2004-10-08 03:36:36 +02:00
|
|
|
{"block_size", PGC_INTERNAL, PRESET_OPTIONS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Shows the size of a disk block."),
|
2003-12-03 19:52:00 +01:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
|
|
|
&block_size,
|
|
|
|
BLCKSZ, BLCKSZ, BLCKSZ, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2005-07-14 07:13:45 +02:00
|
|
|
{
|
|
|
|
{"autovacuum_naptime", PGC_SIGHUP, AUTOVACUUM,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Time to sleep between autovacuum runs."),
|
2006-07-27 10:30:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_UNIT_S
|
2005-07-14 07:13:45 +02:00
|
|
|
},
|
|
|
|
&autovacuum_naptime,
|
2007-06-13 23:24:56 +02:00
|
|
|
60, 1, INT_MAX / 1000, NULL, NULL
|
2005-07-14 07:13:45 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
{"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM,
|
|
|
|
gettext_noop("Minimum number of tuple updates or deletes prior to vacuum."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&autovacuum_vac_thresh,
|
2007-07-24 03:53:56 +02:00
|
|
|
50, 0, INT_MAX, NULL, NULL
|
2005-07-14 07:13:45 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
{"autovacuum_analyze_threshold", PGC_SIGHUP, AUTOVACUUM,
|
|
|
|
gettext_noop("Minimum number of tuple inserts, updates or deletes prior to analyze."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&autovacuum_anl_thresh,
|
2007-07-24 03:53:56 +02:00
|
|
|
50, 0, INT_MAX, NULL, NULL
|
2005-07-14 07:13:45 +02:00
|
|
|
},
|
Fix recently-understood problems with handling of XID freezing, particularly
in PITR scenarios. We now WAL-log the replacement of old XIDs with
FrozenTransactionId, so that such replacement is guaranteed to propagate to
PITR slave databases. Also, rather than relying on hint-bit updates to be
preserved, pg_clog is not truncated until all instances of an XID are known to
have been replaced by FrozenTransactionId. Add new GUC variables and
pg_autovacuum columns to allow management of the freezing policy, so that
users can trade off the size of pg_clog against the amount of freezing work
done. Revise the already-existing code that forces autovacuum of tables
approaching the wraparound point to make it more bulletproof; also, revise the
autovacuum logic so that anti-wraparound vacuuming is done per-table rather
than per-database. initdb forced because of changes in pg_class, pg_database,
and pg_autovacuum catalogs. Heikki Linnakangas, Simon Riggs, and Tom Lane.
2006-11-05 23:42:10 +01:00
|
|
|
{
|
|
|
|
/* see varsup.c for why this is PGC_POSTMASTER not PGC_SIGHUP */
|
|
|
|
{"autovacuum_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM,
|
2006-11-29 15:50:07 +01:00
|
|
|
gettext_noop("Age at which to autovacuum a table to prevent transaction ID wraparound."),
|
Fix recently-understood problems with handling of XID freezing, particularly
in PITR scenarios. We now WAL-log the replacement of old XIDs with
FrozenTransactionId, so that such replacement is guaranteed to propagate to
PITR slave databases. Also, rather than relying on hint-bit updates to be
preserved, pg_clog is not truncated until all instances of an XID are known to
have been replaced by FrozenTransactionId. Add new GUC variables and
pg_autovacuum columns to allow management of the freezing policy, so that
users can trade off the size of pg_clog against the amount of freezing work
done. Revise the already-existing code that forces autovacuum of tables
approaching the wraparound point to make it more bulletproof; also, revise the
autovacuum logic so that anti-wraparound vacuuming is done per-table rather
than per-database. initdb forced because of changes in pg_class, pg_database,
and pg_autovacuum catalogs. Heikki Linnakangas, Simon Riggs, and Tom Lane.
2006-11-05 23:42:10 +01:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&autovacuum_freeze_max_age,
|
|
|
|
200000000, 100000000, 2000000000, NULL, NULL
|
|
|
|
},
|
2007-04-16 20:30:04 +02:00
|
|
|
{
|
|
|
|
/* see max_connections */
|
|
|
|
{"autovacuum_max_workers", PGC_POSTMASTER, AUTOVACUUM,
|
|
|
|
gettext_noop("Sets the maximum number of simultaneously running autovacuum worker processes."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&autovacuum_max_workers,
|
|
|
|
3, 1, INT_MAX / 4, assign_autovacuum_max_workers, NULL
|
|
|
|
},
|
2005-07-14 07:13:45 +02:00
|
|
|
|
2005-07-30 17:17:26 +02:00
|
|
|
{
|
|
|
|
{"tcp_keepalives_idle", PGC_USERSET, CLIENT_CONN_OTHER,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Time between issuing TCP keepalives."),
|
2005-10-15 04:49:52 +02:00
|
|
|
gettext_noop("A value of 0 uses the system default."),
|
2006-07-27 10:30:41 +02:00
|
|
|
GUC_UNIT_S
|
2005-10-15 04:49:52 +02:00
|
|
|
},
|
2005-07-30 17:17:26 +02:00
|
|
|
&tcp_keepalives_idle,
|
|
|
|
0, 0, INT_MAX, assign_tcp_keepalives_idle, show_tcp_keepalives_idle
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"tcp_keepalives_interval", PGC_USERSET, CLIENT_CONN_OTHER,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Time between TCP keepalive retransmits."),
|
2005-10-15 04:49:52 +02:00
|
|
|
gettext_noop("A value of 0 uses the system default."),
|
2006-07-27 10:30:41 +02:00
|
|
|
GUC_UNIT_S
|
2005-10-15 04:49:52 +02:00
|
|
|
},
|
2005-07-30 17:17:26 +02:00
|
|
|
&tcp_keepalives_interval,
|
|
|
|
0, 0, INT_MAX, assign_tcp_keepalives_interval, show_tcp_keepalives_interval
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"tcp_keepalives_count", PGC_USERSET, CLIENT_CONN_OTHER,
|
2005-10-15 04:49:52 +02:00
|
|
|
gettext_noop("Maximum number of TCP keepalive retransmits."),
|
|
|
|
gettext_noop("This controls the number of consecutive keepalive retransmits that can be "
|
|
|
|
"lost before a connection is considered dead. A value of 0 uses the "
|
|
|
|
"system default."),
|
|
|
|
},
|
2005-07-30 17:17:26 +02:00
|
|
|
&tcp_keepalives_count,
|
|
|
|
0, 0, INT_MAX, assign_tcp_keepalives_count, show_tcp_keepalives_count
|
|
|
|
},
|
|
|
|
|
2006-05-02 13:28:56 +02:00
|
|
|
{
|
2006-10-07 21:25:29 +02:00
|
|
|
{"gin_fuzzy_search_limit", PGC_USERSET, CLIENT_CONN_OTHER,
|
2006-10-06 19:14:01 +02:00
|
|
|
gettext_noop("Sets the maximum allowed result for exact search by GIN."),
|
2006-05-02 13:28:56 +02:00
|
|
|
NULL,
|
|
|
|
0
|
|
|
|
},
|
|
|
|
&GinFuzzySearchLimit,
|
|
|
|
0, 0, INT_MAX, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2006-07-26 13:35:56 +02:00
|
|
|
{
|
|
|
|
{"effective_cache_size", PGC_USERSET, QUERY_TUNING_COST,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Sets the planner's assumption about the size of the disk cache."),
|
2006-07-26 13:35:56 +02:00
|
|
|
gettext_noop("That is, the portion of the kernel's disk cache that "
|
|
|
|
"will be used for PostgreSQL data files. This is measured in disk "
|
2006-07-27 10:30:41 +02:00
|
|
|
"pages, which are normally 8 kB each."),
|
|
|
|
GUC_UNIT_BLOCKS,
|
2006-07-26 13:35:56 +02:00
|
|
|
},
|
|
|
|
&effective_cache_size,
|
|
|
|
DEFAULT_EFFECTIVE_CACHE_SIZE, 1, INT_MAX, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2006-09-02 15:12:50 +02:00
|
|
|
{
|
|
|
|
/* Can't be set in postgresql.conf */
|
|
|
|
{"server_version_num", PGC_INTERNAL, PRESET_OPTIONS,
|
|
|
|
gettext_noop("Shows the server version as an integer."),
|
|
|
|
NULL,
|
2006-09-02 19:08:10 +02:00
|
|
|
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
2006-09-02 15:12:50 +02:00
|
|
|
},
|
|
|
|
&server_version_num,
|
|
|
|
PG_VERSION_NUM, PG_VERSION_NUM, PG_VERSION_NUM, NULL, NULL
|
|
|
|
},
|
2007-05-04 03:13:45 +02:00
|
|
|
|
2007-01-09 22:31:17 +01:00
|
|
|
{
|
|
|
|
{"log_temp_files", PGC_USERSET, LOGGING_WHAT,
|
2007-01-09 23:16:46 +01:00
|
|
|
gettext_noop("Log the use of temporary files larger than this number of kilobytes."),
|
2007-01-09 22:31:17 +01:00
|
|
|
gettext_noop("Zero logs all files. The default is -1 (turning this feature off)."),
|
2007-01-09 23:16:46 +01:00
|
|
|
GUC_UNIT_KB
|
2007-01-09 22:31:17 +01:00
|
|
|
},
|
|
|
|
&log_temp_files,
|
|
|
|
-1, -1, INT_MAX, NULL, NULL
|
|
|
|
},
|
2006-09-02 15:12:50 +02:00
|
|
|
|
2003-06-12 00:13:22 +02:00
|
|
|
/* End-of-list marker */
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2003-07-04 18:41:22 +02:00
|
|
|
static struct config_real ConfigureNamesReal[] =
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2006-06-05 04:49:58 +02:00
|
|
|
{"seq_page_cost", PGC_USERSET, QUERY_TUNING_COST,
|
|
|
|
gettext_noop("Sets the planner's estimate of the cost of a "
|
|
|
|
"sequentially fetched disk page."),
|
|
|
|
NULL
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
2006-06-05 04:49:58 +02:00
|
|
|
&seq_page_cost,
|
|
|
|
DEFAULT_SEQ_PAGE_COST, 0, DBL_MAX, NULL, NULL
|
2001-10-28 07:26:15 +01:00
|
|
|
},
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"random_page_cost", PGC_USERSET, QUERY_TUNING_COST,
|
2006-06-05 04:49:58 +02:00
|
|
|
gettext_noop("Sets the planner's estimate of the cost of a "
|
|
|
|
"nonsequentially fetched disk page."),
|
|
|
|
NULL
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&random_page_cost,
|
2001-10-30 06:38:56 +01:00
|
|
|
DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"cpu_tuple_cost", PGC_USERSET, QUERY_TUNING_COST,
|
2006-06-05 04:49:58 +02:00
|
|
|
gettext_noop("Sets the planner's estimate of the cost of "
|
|
|
|
"processing each tuple (row)."),
|
|
|
|
NULL
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&cpu_tuple_cost,
|
2001-10-30 06:38:56 +01:00
|
|
|
DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"cpu_index_tuple_cost", PGC_USERSET, QUERY_TUNING_COST,
|
2006-06-05 04:49:58 +02:00
|
|
|
gettext_noop("Sets the planner's estimate of the cost of "
|
|
|
|
"processing each index entry during an index scan."),
|
|
|
|
NULL
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&cpu_index_tuple_cost,
|
2001-10-30 06:38:56 +01:00
|
|
|
DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"cpu_operator_cost", PGC_USERSET, QUERY_TUNING_COST,
|
2006-06-05 04:49:58 +02:00
|
|
|
gettext_noop("Sets the planner's estimate of the cost of "
|
|
|
|
"processing each operator or function call."),
|
|
|
|
NULL
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&cpu_operator_cost,
|
2001-10-30 06:38:56 +01:00
|
|
|
DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"geqo_selection_bias", PGC_USERSET, QUERY_TUNING_GEQO,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("GEQO: selective pressure within the population."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&Geqo_selection_bias,
|
2001-10-30 06:38:56 +01:00
|
|
|
DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS,
|
|
|
|
MAX_GEQO_SELECTION_BIAS, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
|
2005-03-04 21:21:07 +01:00
|
|
|
{
|
2007-09-25 22:03:38 +02:00
|
|
|
{"bgwriter_lru_multiplier", PGC_SIGHUP, RESOURCES,
|
2008-03-06 17:31:42 +01:00
|
|
|
gettext_noop("Multiple of the average buffer usage to free per round."),
|
2005-03-04 21:21:07 +01:00
|
|
|
NULL
|
|
|
|
},
|
2007-09-25 22:03:38 +02:00
|
|
|
&bgwriter_lru_multiplier,
|
|
|
|
2.0, 0.0, 10.0, NULL, NULL
|
2005-03-04 21:21:07 +01:00
|
|
|
},
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"seed", PGC_USERSET, UNGROUPED,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the seed for random-number generation."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
2002-05-17 03:19:19 +02:00
|
|
|
&phony_random_seed,
|
2008-03-10 13:39:23 +01:00
|
|
|
0.0, -1.0, 1.0, assign_random_seed, show_random_seed
|
2002-05-17 03:19:19 +02:00
|
|
|
},
|
|
|
|
|
2005-07-14 07:13:45 +02:00
|
|
|
{
|
|
|
|
{"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM,
|
|
|
|
gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&autovacuum_vac_scale,
|
2006-09-03 01:12:16 +02:00
|
|
|
0.2, 0.0, 100.0, NULL, NULL
|
2005-07-14 07:13:45 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
{"autovacuum_analyze_scale_factor", PGC_SIGHUP, AUTOVACUUM,
|
|
|
|
gettext_noop("Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&autovacuum_anl_scale,
|
2006-09-03 01:12:16 +02:00
|
|
|
0.1, 0.0, 100.0, NULL, NULL
|
2005-07-14 07:13:45 +02:00
|
|
|
},
|
|
|
|
|
2007-06-28 02:02:40 +02:00
|
|
|
{
|
|
|
|
{"checkpoint_completion_target", PGC_SIGHUP, WAL_CHECKPOINTS,
|
|
|
|
gettext_noop("Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&CheckPointCompletionTarget,
|
|
|
|
0.5, 0.0, 1.0, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2003-06-12 00:13:22 +02:00
|
|
|
/* End-of-list marker */
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{NULL, 0, 0, NULL, NULL}, NULL, 0.0, 0.0, 0.0, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2003-07-04 18:41:22 +02:00
|
|
|
static struct config_string ConfigureNamesString[] =
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
{
|
|
|
|
{"archive_command", PGC_SIGHUP, WAL_SETTINGS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Sets the shell command that will be called to archive a WAL file."),
|
|
|
|
NULL
|
2004-08-29 07:07:03 +02:00
|
|
|
},
|
|
|
|
&XLogArchiveCommand,
|
2007-09-27 00:36:30 +02:00
|
|
|
"", NULL, show_archive_command
|
2004-08-29 07:07:03 +02:00
|
|
|
},
|
2004-07-19 04:47:16 +02:00
|
|
|
|
2006-05-21 22:10:42 +02:00
|
|
|
{
|
|
|
|
{"backslash_quote", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
|
|
|
|
gettext_noop("Sets whether \"\\'\" is allowed in string literals."),
|
|
|
|
gettext_noop("Valid values are ON, OFF, and SAFE_ENCODING.")
|
|
|
|
},
|
|
|
|
&backslash_quote_string,
|
|
|
|
"safe_encoding", assign_backslash_quote, NULL
|
|
|
|
},
|
|
|
|
|
Commit to match discussed elog() changes. Only update is that LOG is
now just below FATAL in server_min_messages. Added more text to
highlight ordering difference between it and client_min_messages.
---------------------------------------------------------------------------
REALLYFATAL => PANIC
STOP => PANIC
New INFO level the prints to client by default
New LOG level the prints to server log by default
Cause VACUUM information to print only to the client
NOTICE => INFO where purely information messages are sent
DEBUG => LOG for purely server status messages
DEBUG removed, kept as backward compatible
DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1 added
DebugLvl removed in favor of new DEBUG[1-5] symbols
New server_min_messages GUC parameter with values:
DEBUG[5-1], INFO, NOTICE, ERROR, LOG, FATAL, PANIC
New client_min_messages GUC parameter with values:
DEBUG[5-1], LOG, INFO, NOTICE, ERROR, FATAL, PANIC
Server startup now logged with LOG instead of DEBUG
Remove debug_level GUC parameter
elog() numbers now start at 10
Add test to print error message if older elog() values are passed to elog()
Bootstrap mode now has a -d that requires an argument, like postmaster
2002-03-02 22:39:36 +01:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"client_encoding", PGC_USERSET, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the client's character set encoding."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
2006-02-12 23:32:43 +01:00
|
|
|
GUC_IS_NAME | GUC_REPORT
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
2003-04-25 21:45:10 +02:00
|
|
|
&client_encoding_string,
|
2002-05-17 03:19:19 +02:00
|
|
|
"SQL_ASCII", assign_client_encoding, NULL
|
Commit to match discussed elog() changes. Only update is that LOG is
now just below FATAL in server_min_messages. Added more text to
highlight ordering difference between it and client_min_messages.
---------------------------------------------------------------------------
REALLYFATAL => PANIC
STOP => PANIC
New INFO level the prints to client by default
New LOG level the prints to server log by default
Cause VACUUM information to print only to the client
NOTICE => INFO where purely information messages are sent
DEBUG => LOG for purely server status messages
DEBUG removed, kept as backward compatible
DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1 added
DebugLvl removed in favor of new DEBUG[1-5] symbols
New server_min_messages GUC parameter with values:
DEBUG[5-1], INFO, NOTICE, ERROR, LOG, FATAL, PANIC
New client_min_messages GUC parameter with values:
DEBUG[5-1], LOG, INFO, NOTICE, ERROR, FATAL, PANIC
Server startup now logged with LOG instead of DEBUG
Remove debug_level GUC parameter
elog() numbers now start at 10
Add test to print error message if older elog() values are passed to elog()
Bootstrap mode now has a -d that requires an argument, like postmaster
2002-03-02 22:39:36 +01:00
|
|
|
},
|
|
|
|
|
2004-03-09 05:43:07 +01:00
|
|
|
{
|
|
|
|
{"log_line_prefix", PGC_SIGHUP, LOGGING_WHAT,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Controls information prefixed to each log line."),
|
|
|
|
gettext_noop("If blank, no prefix is used.")
|
2004-03-09 05:43:07 +01:00
|
|
|
},
|
|
|
|
&Log_line_prefix,
|
|
|
|
"", NULL, NULL
|
|
|
|
},
|
|
|
|
|
2007-08-04 03:26:54 +02:00
|
|
|
{
|
|
|
|
{"log_timezone", PGC_SIGHUP, LOGGING_WHAT,
|
|
|
|
gettext_noop("Sets the time zone to use in log messages."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&log_timezone_string,
|
|
|
|
"UNKNOWN", assign_log_timezone, show_log_timezone
|
|
|
|
},
|
2004-03-09 05:43:07 +01:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"DateStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the display format for date and time values."),
|
2003-08-01 03:23:11 +02:00
|
|
|
gettext_noop("Also controls interpretation of ambiguous "
|
2003-09-25 08:58:07 +02:00
|
|
|
"date inputs."),
|
2003-07-04 18:41:22 +02:00
|
|
|
GUC_LIST_INPUT | GUC_REPORT
|
|
|
|
},
|
2003-04-25 21:45:10 +02:00
|
|
|
&datestyle_string,
|
2003-07-29 02:03:19 +02:00
|
|
|
"ISO, MDY", assign_datestyle, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-05-17 19:44:18 +02:00
|
|
|
|
2004-11-05 20:17:13 +01:00
|
|
|
{
|
|
|
|
{"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
|
|
|
gettext_noop("Sets the default tablespace to create tables and indexes in."),
|
2006-02-12 23:32:43 +01:00
|
|
|
gettext_noop("An empty string selects the database's default tablespace."),
|
2006-10-04 02:30:14 +02:00
|
|
|
GUC_IS_NAME
|
2004-11-05 20:17:13 +01:00
|
|
|
},
|
|
|
|
&default_tablespace,
|
|
|
|
"", assign_default_tablespace, NULL
|
|
|
|
},
|
|
|
|
|
2007-06-03 19:08:34 +02:00
|
|
|
{
|
|
|
|
{"temp_tablespaces", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
|
|
|
gettext_noop("Sets the tablespace(s) to use for temporary tables and sort files."),
|
|
|
|
NULL,
|
|
|
|
GUC_LIST_INPUT | GUC_LIST_QUOTE
|
|
|
|
},
|
|
|
|
&temp_tablespaces,
|
|
|
|
"", assign_temp_tablespaces, NULL
|
|
|
|
},
|
|
|
|
|
2002-04-01 05:34:27 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the transaction isolation level of each new transaction."),
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("Each SQL transaction has an isolation level, which "
|
2004-08-29 07:07:03 +02:00
|
|
|
"can be either \"read uncommitted\", \"read committed\", \"repeatable read\", or \"serializable\".")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&default_iso_level_string,
|
2002-05-17 03:19:19 +02:00
|
|
|
"read committed", assign_defaultxactisolevel, NULL
|
2002-04-01 05:34:27 +02:00
|
|
|
},
|
|
|
|
|
2007-03-20 00:38:32 +01:00
|
|
|
{
|
|
|
|
{"session_replication_role", PGC_SUSET, CLIENT_CONN_STATEMENT,
|
2008-01-27 20:12:28 +01:00
|
|
|
gettext_noop("Sets the session's behavior for triggers and rewrite rules."),
|
2007-03-20 00:38:32 +01:00
|
|
|
gettext_noop("Each session can be either"
|
2007-12-27 14:02:48 +01:00
|
|
|
" \"origin\", \"replica\", or \"local\".")
|
2007-03-20 00:38:32 +01:00
|
|
|
},
|
|
|
|
&session_replication_role_string,
|
|
|
|
"origin", assign_session_replication_role, NULL
|
|
|
|
},
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"dynamic_library_path", PGC_SUSET, CLIENT_CONN_OTHER,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the path for dynamically loadable modules."),
|
2003-07-04 18:41:22 +02:00
|
|
|
gettext_noop("If a dynamically loadable module needs to be opened and "
|
2003-09-29 02:05:25 +02:00
|
|
|
"the specified name does not have a directory component (i.e., the "
|
2003-07-04 18:41:22 +02:00
|
|
|
"name does not contain a slash), the system will search this path for "
|
2004-10-22 21:48:19 +02:00
|
|
|
"the specified file."),
|
|
|
|
GUC_SUPERUSER_ONLY
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&Dynamic_library_path,
|
2004-07-12 04:22:51 +02:00
|
|
|
"$libdir", NULL, NULL
|
2002-05-17 03:19:19 +02:00
|
|
|
},
|
|
|
|
|
2007-11-09 18:31:07 +01:00
|
|
|
{
|
|
|
|
{"krb_realm", PGC_POSTMASTER, CONN_AUTH_SECURITY,
|
|
|
|
gettext_noop("Sets realm to match Kerberos and GSSAPI users against."),
|
|
|
|
NULL,
|
|
|
|
GUC_SUPERUSER_ONLY
|
|
|
|
},
|
|
|
|
&pg_krb_realm,
|
|
|
|
NULL, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"krb_server_keyfile", PGC_POSTMASTER, CONN_AUTH_SECURITY,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the location of the Kerberos server key file."),
|
2004-10-22 21:48:19 +02:00
|
|
|
NULL,
|
|
|
|
GUC_SUPERUSER_ONLY
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&pg_krb_server_keyfile,
|
2001-10-30 06:38:56 +01:00
|
|
|
PG_KRB_SRVTAB, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-11-14 20:13:27 +01:00
|
|
|
|
2005-06-04 22:42:43 +02:00
|
|
|
{
|
|
|
|
{"krb_srvname", PGC_POSTMASTER, CONN_AUTH_SECURITY,
|
|
|
|
gettext_noop("Sets the name of the Kerberos service."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&pg_krb_srvnam,
|
|
|
|
PG_KRB_SRVNAM, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2005-06-14 19:43:14 +02:00
|
|
|
{
|
|
|
|
{"krb_server_hostname", PGC_POSTMASTER, CONN_AUTH_SECURITY,
|
|
|
|
gettext_noop("Sets the hostname of the Kerberos server."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&pg_krb_server_hostname,
|
|
|
|
NULL, NULL, NULL
|
|
|
|
},
|
|
|
|
|
2003-07-22 22:29:13 +02:00
|
|
|
{
|
2005-05-15 02:26:19 +02:00
|
|
|
{"bonjour_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
|
|
|
gettext_noop("Sets the Bonjour broadcast service name."),
|
2003-07-22 22:29:13 +02:00
|
|
|
NULL
|
|
|
|
},
|
2005-05-15 02:26:19 +02:00
|
|
|
&bonjour_name,
|
2003-07-22 22:29:13 +02:00
|
|
|
"", NULL, NULL
|
|
|
|
},
|
|
|
|
|
2002-09-10 18:09:02 +02:00
|
|
|
/* See main.c about why defaults for LC_foo are not all alike */
|
|
|
|
|
2003-04-25 21:45:10 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"lc_collate", PGC_INTERNAL, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Shows the collation order locale."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
|
|
|
&locale_collate,
|
2003-04-25 21:45:10 +02:00
|
|
|
"C", NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"lc_ctype", PGC_INTERNAL, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Shows the character classification and case conversion locale."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
|
|
|
&locale_ctype,
|
2003-04-25 21:45:10 +02:00
|
|
|
"C", NULL, NULL
|
|
|
|
},
|
|
|
|
|
2002-04-03 07:39:33 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"lc_messages", PGC_SUSET, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the language in which messages are displayed."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&locale_messages,
|
2002-05-17 03:19:19 +02:00
|
|
|
"", locale_messages_assign, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"lc_monetary", PGC_USERSET, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the locale for formatting monetary amounts."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&locale_monetary,
|
2002-09-10 18:09:02 +02:00
|
|
|
"C", locale_monetary_assign, NULL
|
2002-05-17 03:19:19 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"lc_numeric", PGC_USERSET, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the locale for formatting numbers."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&locale_numeric,
|
2002-09-10 18:09:02 +02:00
|
|
|
"C", locale_numeric_assign, NULL
|
2002-05-17 03:19:19 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"lc_time", PGC_USERSET, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the locale for formatting date and time values."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&locale_time,
|
2002-09-10 18:09:02 +02:00
|
|
|
"C", locale_time_assign, NULL
|
2002-04-03 07:39:33 +02:00
|
|
|
},
|
|
|
|
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
2003-03-20 05:51:44 +01:00
|
|
|
{
|
2006-08-15 20:26:59 +02:00
|
|
|
{"shared_preload_libraries", PGC_POSTMASTER, RESOURCES_KERNEL,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Lists shared libraries to preload into server."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
2004-10-22 21:48:19 +02:00
|
|
|
GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
2006-08-15 20:26:59 +02:00
|
|
|
&shared_preload_libraries_string,
|
|
|
|
"", NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"local_preload_libraries", PGC_BACKEND, CLIENT_CONN_OTHER,
|
|
|
|
gettext_noop("Lists shared libraries to preload into each backend."),
|
|
|
|
NULL,
|
|
|
|
GUC_LIST_INPUT | GUC_LIST_QUOTE
|
|
|
|
},
|
|
|
|
&local_preload_libraries_string,
|
2004-07-12 02:09:07 +02:00
|
|
|
"", NULL, NULL
|
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space
> that has to be duplicated into child processes will cost something per
> child launch, even if the child never uses it. But these are only
> arguments that it might not *always* be a prudent thing to do, not that
> we shouldn't give the DBA the tool to do it if he wants. So fire away.
Here is a patch for the above, including a documentation update. It
creates a new GUC variable "preload_libraries", that accepts a list in
the form:
preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2'
If ":initfunc" is omitted or not found, no initialization function is
executed, but the library is still preloaded. If "$libdir/mylib" isn't
found, the postmaster refuses to start.
In my testing with PL/R, it reduces the first call to a PL/R function
(after connecting) from almost 2 seconds, down to about 8 ms.
Joe Conway
2003-03-20 05:51:44 +01:00
|
|
|
},
|
|
|
|
|
2003-02-06 21:25:33 +01:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"regex_flavor", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the regular expression \"flavor\"."),
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("This can be set to advanced, extended, or basic.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
®ex_flavor_string,
|
2003-02-06 21:25:33 +01:00
|
|
|
"advanced", assign_regex_flavor, NULL
|
|
|
|
},
|
|
|
|
|
2002-04-03 07:39:33 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"search_path", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the schema search order for names that are not schema-qualified."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_LIST_INPUT | GUC_LIST_QUOTE
|
|
|
|
},
|
2002-05-17 03:19:19 +02:00
|
|
|
&namespace_search_path,
|
2005-12-23 01:38:04 +01:00
|
|
|
"\"$user\",public", assign_search_path, NULL
|
2002-04-03 07:39:33 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
/* Can't be set in postgresql.conf */
|
|
|
|
{"server_encoding", PGC_INTERNAL, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the server (database) character set encoding."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
2006-02-12 23:32:43 +01:00
|
|
|
GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
2003-04-25 21:45:10 +02:00
|
|
|
&server_encoding_string,
|
|
|
|
"SQL_ASCII", NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
/* Can't be set in postgresql.conf */
|
2004-10-08 03:36:36 +02:00
|
|
|
{"server_version", PGC_INTERNAL, PRESET_OPTIONS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Shows the server version."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
2003-04-25 21:45:10 +02:00
|
|
|
&server_version_string,
|
|
|
|
PG_VERSION, NULL, NULL
|
2002-04-03 07:39:33 +02:00
|
|
|
},
|
|
|
|
|
2005-07-26 00:12:34 +02:00
|
|
|
{
|
|
|
|
/* Not for general use --- used by SET ROLE */
|
|
|
|
{"role", PGC_USERSET, UNGROUPED,
|
|
|
|
gettext_noop("Sets the current role."),
|
|
|
|
NULL,
|
2006-02-12 23:32:43 +01:00
|
|
|
GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
2005-07-26 00:12:34 +02:00
|
|
|
},
|
|
|
|
&role_string,
|
|
|
|
"none", assign_role, show_role
|
|
|
|
},
|
|
|
|
|
Commit to match discussed elog() changes. Only update is that LOG is
now just below FATAL in server_min_messages. Added more text to
highlight ordering difference between it and client_min_messages.
---------------------------------------------------------------------------
REALLYFATAL => PANIC
STOP => PANIC
New INFO level the prints to client by default
New LOG level the prints to server log by default
Cause VACUUM information to print only to the client
NOTICE => INFO where purely information messages are sent
DEBUG => LOG for purely server status messages
DEBUG removed, kept as backward compatible
DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1 added
DebugLvl removed in favor of new DEBUG[1-5] symbols
New server_min_messages GUC parameter with values:
DEBUG[5-1], INFO, NOTICE, ERROR, LOG, FATAL, PANIC
New client_min_messages GUC parameter with values:
DEBUG[5-1], LOG, INFO, NOTICE, ERROR, FATAL, PANIC
Server startup now logged with LOG instead of DEBUG
Remove debug_level GUC parameter
elog() numbers now start at 10
Add test to print error message if older elog() values are passed to elog()
Bootstrap mode now has a -d that requires an argument, like postmaster
2002-03-02 22:39:36 +01:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
/* Not for general use --- used by SET SESSION AUTHORIZATION */
|
|
|
|
{"session_authorization", PGC_USERSET, UNGROUPED,
|
2003-12-01 04:55:21 +01:00
|
|
|
gettext_noop("Sets the session user name."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
2006-02-12 23:32:43 +01:00
|
|
|
GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
2002-05-17 03:19:19 +02:00
|
|
|
&session_authorization_string,
|
|
|
|
NULL, assign_session_authorization, show_session_authorization
|
Commit to match discussed elog() changes. Only update is that LOG is
now just below FATAL in server_min_messages. Added more text to
highlight ordering difference between it and client_min_messages.
---------------------------------------------------------------------------
REALLYFATAL => PANIC
STOP => PANIC
New INFO level the prints to client by default
New LOG level the prints to server log by default
Cause VACUUM information to print only to the client
NOTICE => INFO where purely information messages are sent
DEBUG => LOG for purely server status messages
DEBUG removed, kept as backward compatible
DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1 added
DebugLvl removed in favor of new DEBUG[1-5] symbols
New server_min_messages GUC parameter with values:
DEBUG[5-1], INFO, NOTICE, ERROR, LOG, FATAL, PANIC
New client_min_messages GUC parameter with values:
DEBUG[5-1], LOG, INFO, NOTICE, ERROR, FATAL, PANIC
Server startup now logged with LOG instead of DEBUG
Remove debug_level GUC parameter
elog() numbers now start at 10
Add test to print error message if older elog() values are passed to elog()
Bootstrap mode now has a -d that requires an argument, like postmaster
2002-03-02 22:39:36 +01:00
|
|
|
},
|
|
|
|
|
2004-04-05 05:02:11 +02:00
|
|
|
{
|
2004-07-24 21:51:23 +02:00
|
|
|
{"log_destination", PGC_SIGHUP, LOGGING_WHERE,
|
2004-08-29 07:07:03 +02:00
|
|
|
gettext_noop("Sets the destination for server log output."),
|
2007-08-21 03:11:32 +02:00
|
|
|
gettext_noop("Valid values are combinations of \"stderr\", "
|
|
|
|
"\"syslog\", \"csvlog\", and \"eventlog\", "
|
|
|
|
"depending on the platform."),
|
2004-08-29 07:07:03 +02:00
|
|
|
GUC_LIST_INPUT
|
2004-04-05 05:02:11 +02:00
|
|
|
},
|
|
|
|
&log_destination_string,
|
|
|
|
"stderr", assign_log_destination, NULL
|
|
|
|
},
|
2004-08-06 01:32:13 +02:00
|
|
|
{
|
|
|
|
{"log_directory", PGC_SIGHUP, LOGGING_WHERE,
|
2004-08-31 06:53:44 +02:00
|
|
|
gettext_noop("Sets the destination directory for log files."),
|
Wording cleanup for error messages. Also change can't -> cannot.
Standard English uses "may", "can", and "might" in different ways:
may - permission, "You may borrow my rake."
can - ability, "I can lift that log."
might - possibility, "It might rain today."
Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice. Similarly, "It may crash" is better stated, "It might crash".
2007-02-01 20:10:30 +01:00
|
|
|
gettext_noop("Can be specified as relative to the data directory "
|
2004-10-22 21:48:19 +02:00
|
|
|
"or as absolute path."),
|
|
|
|
GUC_SUPERUSER_ONLY
|
2004-08-06 01:32:13 +02:00
|
|
|
},
|
|
|
|
&Log_directory,
|
2004-10-10 01:13:22 +02:00
|
|
|
"pg_log", assign_canonical_path, NULL
|
2004-08-06 01:32:13 +02:00
|
|
|
},
|
|
|
|
{
|
2004-08-31 06:53:44 +02:00
|
|
|
{"log_filename", PGC_SIGHUP, LOGGING_WHERE,
|
|
|
|
gettext_noop("Sets the file name pattern for log files."),
|
2004-10-22 21:48:19 +02:00
|
|
|
NULL,
|
|
|
|
GUC_SUPERUSER_ONLY
|
2004-08-06 01:32:13 +02:00
|
|
|
},
|
2004-08-31 06:53:44 +02:00
|
|
|
&Log_filename,
|
|
|
|
"postgresql-%Y-%m-%d_%H%M%S.log", NULL, NULL
|
2004-08-06 01:32:13 +02:00
|
|
|
},
|
2004-04-05 05:02:11 +02:00
|
|
|
|
2002-04-21 02:22:52 +02:00
|
|
|
#ifdef HAVE_SYSLOG
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2005-10-14 22:53:56 +02:00
|
|
|
{"syslog_facility", PGC_SIGHUP, LOGGING_WHERE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the syslog \"facility\" to be used when syslog enabled."),
|
2003-09-25 08:58:07 +02:00
|
|
|
gettext_noop("Valid values are LOCAL0, LOCAL1, LOCAL2, LOCAL3, "
|
|
|
|
"LOCAL4, LOCAL5, LOCAL6, LOCAL7.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
2005-10-14 22:53:56 +02:00
|
|
|
&syslog_facility_str,
|
|
|
|
"LOCAL0", assign_syslog_facility, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
|
|
|
{
|
2005-10-14 22:53:56 +02:00
|
|
|
{"syslog_ident", PGC_SIGHUP, LOGGING_WHERE,
|
|
|
|
gettext_noop("Sets the program name used to identify PostgreSQL "
|
|
|
|
"messages in syslog."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
2005-10-14 22:53:56 +02:00
|
|
|
&syslog_ident_str,
|
|
|
|
"postgres", assign_syslog_ident, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2000-11-13 22:35:03 +01:00
|
|
|
#endif
|
2000-11-01 22:14:03 +01:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the time zone for displaying and interpreting time stamps."),
|
2004-12-20 19:15:07 +01:00
|
|
|
NULL,
|
|
|
|
GUC_REPORT
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&timezone_string,
|
2002-05-17 03:19:19 +02:00
|
|
|
"UNKNOWN", assign_timezone, show_timezone
|
|
|
|
},
|
2006-07-25 05:51:23 +02:00
|
|
|
{
|
|
|
|
{"timezone_abbreviations", PGC_USERSET, CLIENT_CONN_LOCALE,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Selects a file of time zone abbreviations."),
|
2006-07-25 05:51:23 +02:00
|
|
|
NULL,
|
|
|
|
},
|
2006-07-29 05:02:56 +02:00
|
|
|
&timezone_abbreviations_string,
|
|
|
|
"UNKNOWN", assign_timezone_abbreviations, NULL
|
2006-07-25 05:51:23 +02:00
|
|
|
},
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
2003-12-01 04:55:21 +01:00
|
|
|
gettext_noop("Sets the current transaction's isolation level."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL,
|
|
|
|
GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
|
|
|
|
},
|
2002-05-17 03:19:19 +02:00
|
|
|
&XactIsoLevel_string,
|
|
|
|
NULL, assign_XactIsoLevel, show_XactIsoLevel
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"unix_socket_group", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the owning group of the Unix-domain socket."),
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("The owning user of the socket is always the user "
|
|
|
|
"that starts the server.")
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&Unix_socket_group,
|
2001-10-30 06:38:56 +01:00
|
|
|
"", NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-03-16 06:44:33 +01:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"unix_socket_directory", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
2003-10-19 00:59:09 +02:00
|
|
|
gettext_noop("Sets the directory where the Unix-domain socket will be created."),
|
2004-10-22 21:48:19 +02:00
|
|
|
NULL,
|
|
|
|
GUC_SUPERUSER_ONLY
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
|
|
|
&UnixSocketDir,
|
2004-07-11 23:34:04 +02:00
|
|
|
"", assign_canonical_path, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
UUNET is looking into offering PostgreSQL as a part of a managed web
hosting product, on both shared and dedicated machines. We currently
offer Oracle and MySQL, and it would be a nice middle-ground.
However, as shipped, PostgreSQL lacks the following features we need
that MySQL has:
1. The ability to listen only on a particular IP address. Each
hosting customer has their own IP address, on which all of their
servers (http, ftp, real media, etc.) run.
2. The ability to place the Unix-domain socket in a mode 700 directory.
This allows us to automatically create an empty database, with an
empty DBA password, for new or upgrading customers without having
to interactively set a DBA password and communicate it to (or from)
the customer. This in turn cuts down our install and upgrade times.
3. The ability to connect to the Unix-domain socket from within a
change-rooted environment. We run CGI programs chrooted to the
user's home directory, which is another reason why we need to be
able to specify where the Unix-domain socket is, instead of /tmp.
4. The ability to, if run as root, open a pid file in /var/run as
root, and then setuid to the desired user. (mysqld -u can almost
do this; I had to patch it, too).
The patch below fixes problem 1-3. I plan to address #4, also, but
haven't done so yet. These diffs are big enough that they should give
the PG development team something to think about in the meantime :-)
Also, I'm about to leave for 2 weeks' vacation, so I thought I'd get
out what I have, which works (for the problems it tackles), now.
With these changes, we can set up and run PostgreSQL with scripts the
same way we can with apache or proftpd or mysql.
In summary, this patch makes the following enhancements:
1. Adds an environment variable PGUNIXSOCKET, analogous to MYSQL_UNIX_PORT,
and command line options -k --unix-socket to the relevant programs.
2. Adds a -h option to postmaster to set the hostname or IP address to
listen on instead of the default INADDR_ANY.
3. Extends some library interfaces to support the above.
4. Fixes a few memory leaks in PQconnectdb().
The default behavior is unchanged from stock 7.0.2; if you don't use
any of these new features, they don't change the operation.
David J. MacKenzie
2000-11-13 16:18:15 +01:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2004-03-23 02:23:48 +01:00
|
|
|
{"listen_addresses", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
2004-08-08 22:17:36 +02:00
|
|
|
gettext_noop("Sets the host name or IP address(es) to listen to."),
|
|
|
|
NULL,
|
|
|
|
GUC_LIST_INPUT
|
2003-07-04 18:41:22 +02:00
|
|
|
},
|
2004-03-23 02:23:48 +01:00
|
|
|
&ListenAddresses,
|
|
|
|
"localhost", NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
UUNET is looking into offering PostgreSQL as a part of a managed web
hosting product, on both shared and dedicated machines. We currently
offer Oracle and MySQL, and it would be a nice middle-ground.
However, as shipped, PostgreSQL lacks the following features we need
that MySQL has:
1. The ability to listen only on a particular IP address. Each
hosting customer has their own IP address, on which all of their
servers (http, ftp, real media, etc.) run.
2. The ability to place the Unix-domain socket in a mode 700 directory.
This allows us to automatically create an empty database, with an
empty DBA password, for new or upgrading customers without having
to interactively set a DBA password and communicate it to (or from)
the customer. This in turn cuts down our install and upgrade times.
3. The ability to connect to the Unix-domain socket from within a
change-rooted environment. We run CGI programs chrooted to the
user's home directory, which is another reason why we need to be
able to specify where the Unix-domain socket is, instead of /tmp.
4. The ability to, if run as root, open a pid file in /var/run as
root, and then setuid to the desired user. (mysqld -u can almost
do this; I had to patch it, too).
The patch below fixes problem 1-3. I plan to address #4, also, but
haven't done so yet. These diffs are big enough that they should give
the PG development team something to think about in the meantime :-)
Also, I'm about to leave for 2 weeks' vacation, so I thought I'd get
out what I have, which works (for the problems it tackles), now.
With these changes, we can set up and run PostgreSQL with scripts the
same way we can with apache or proftpd or mysql.
In summary, this patch makes the following enhancements:
1. Adds an environment variable PGUNIXSOCKET, analogous to MYSQL_UNIX_PORT,
and command line options -k --unix-socket to the relevant programs.
2. Adds a -h option to postmaster to set the hostname or IP address to
listen on instead of the default INADDR_ANY.
3. Extends some library interfaces to support the above.
4. Fixes a few memory leaks in PQconnectdb().
The default behavior is unchanged from stock 7.0.2; if you don't use
any of these new features, they don't change the operation.
David J. MacKenzie
2000-11-13 16:18:15 +01:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Selects the method used for forcing WAL updates to disk."),
|
2003-07-04 18:41:22 +02:00
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&XLOG_sync_method,
|
2002-05-17 03:19:19 +02:00
|
|
|
XLOG_sync_method_default, assign_xlog_sync_method, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
},
|
2001-03-16 06:44:33 +01:00
|
|
|
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2005-08-21 05:39:37 +02:00
|
|
|
{"custom_variable_classes", PGC_SIGHUP, CUSTOM_OPTIONS,
|
2004-10-22 21:48:19 +02:00
|
|
|
gettext_noop("Sets the list of known custom variable classes."),
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
NULL,
|
|
|
|
GUC_LIST_INPUT | GUC_LIST_QUOTE
|
|
|
|
},
|
|
|
|
&custom_variable_classes,
|
|
|
|
NULL, assign_custom_variable_classes, NULL
|
|
|
|
},
|
|
|
|
|
2004-07-11 02:18:45 +02:00
|
|
|
{
|
2004-10-10 01:13:22 +02:00
|
|
|
{"data_directory", PGC_POSTMASTER, FILE_LOCATIONS,
|
2005-10-15 04:49:52 +02:00
|
|
|
gettext_noop("Sets the server's data directory."),
|
|
|
|
NULL,
|
|
|
|
GUC_SUPERUSER_ONLY
|
2004-10-08 03:36:36 +02:00
|
|
|
},
|
2004-10-10 01:13:22 +02:00
|
|
|
&data_directory,
|
|
|
|
NULL, NULL, NULL
|
2004-07-11 02:18:45 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2004-10-10 01:13:22 +02:00
|
|
|
{"config_file", PGC_POSTMASTER, FILE_LOCATIONS,
|
2005-10-15 04:49:52 +02:00
|
|
|
gettext_noop("Sets the server's main configuration file."),
|
|
|
|
NULL,
|
|
|
|
GUC_DISALLOW_IN_FILE | GUC_SUPERUSER_ONLY
|
2004-10-10 01:13:22 +02:00
|
|
|
},
|
|
|
|
&ConfigFileName,
|
|
|
|
NULL, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"hba_file", PGC_POSTMASTER, FILE_LOCATIONS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Sets the server's \"hba\" configuration file."),
|
2005-10-15 04:49:52 +02:00
|
|
|
NULL,
|
|
|
|
GUC_SUPERUSER_ONLY
|
2004-10-08 03:36:36 +02:00
|
|
|
},
|
2004-10-10 01:13:22 +02:00
|
|
|
&HbaFileName,
|
|
|
|
NULL, NULL, NULL
|
2004-07-11 02:18:45 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2004-10-10 01:13:22 +02:00
|
|
|
{"ident_file", PGC_POSTMASTER, FILE_LOCATIONS,
|
2006-12-06 18:35:49 +01:00
|
|
|
gettext_noop("Sets the server's \"ident\" configuration file."),
|
2005-10-15 04:49:52 +02:00
|
|
|
NULL,
|
|
|
|
GUC_SUPERUSER_ONLY
|
2004-10-08 03:36:36 +02:00
|
|
|
},
|
2004-10-10 01:13:22 +02:00
|
|
|
&IdentFileName,
|
|
|
|
NULL, NULL, NULL
|
2004-07-11 02:18:45 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2004-10-10 01:13:22 +02:00
|
|
|
{"external_pid_file", PGC_POSTMASTER, FILE_LOCATIONS,
|
2005-10-15 04:49:52 +02:00
|
|
|
gettext_noop("Writes the postmaster PID to the specified file."),
|
|
|
|
NULL,
|
|
|
|
GUC_SUPERUSER_ONLY
|
2004-10-08 03:36:36 +02:00
|
|
|
},
|
2004-10-10 01:13:22 +02:00
|
|
|
&external_pid_file,
|
2004-07-11 23:34:04 +02:00
|
|
|
NULL, assign_canonical_path, NULL
|
2004-07-11 02:18:45 +02:00
|
|
|
},
|
|
|
|
|
2007-01-19 17:58:46 +01:00
|
|
|
{
|
|
|
|
{"xmlbinary", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
|
|
|
gettext_noop("Sets how binary values are to be encoded in XML."),
|
|
|
|
gettext_noop("Valid values are BASE64 and HEX.")
|
|
|
|
},
|
|
|
|
&xmlbinary_string,
|
|
|
|
"base64", assign_xmlbinary, NULL
|
|
|
|
},
|
|
|
|
|
2007-01-25 12:53:52 +01:00
|
|
|
{
|
|
|
|
{"xmloption", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
|
|
|
gettext_noop("Sets whether XML data in implicit parsing and serialization "
|
|
|
|
"operations is to be considered as documents or content fragments."),
|
|
|
|
gettext_noop("Valid values are DOCUMENT and CONTENT.")
|
|
|
|
},
|
|
|
|
&xmloption_string,
|
|
|
|
"content", assign_xmloption, NULL
|
|
|
|
},
|
|
|
|
|
2007-08-21 03:11:32 +02:00
|
|
|
{
|
|
|
|
{"default_text_search_config", PGC_USERSET, CLIENT_CONN_LOCALE,
|
|
|
|
gettext_noop("Sets default text search configuration."),
|
|
|
|
NULL
|
|
|
|
},
|
|
|
|
&TSCurrentConfig,
|
|
|
|
"pg_catalog.simple", assignTSCurrentConfig, NULL
|
|
|
|
},
|
|
|
|
|
2007-02-16 18:07:00 +01:00
|
|
|
#ifdef USE_SSL
|
2007-02-16 03:59:41 +01:00
|
|
|
{
|
|
|
|
{"ssl_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
|
|
|
|
gettext_noop("Sets the list of allowed SSL ciphers."),
|
|
|
|
NULL,
|
|
|
|
GUC_SUPERUSER_ONLY
|
|
|
|
},
|
|
|
|
&SSLCipherSuites,
|
|
|
|
"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH", NULL, NULL
|
|
|
|
},
|
2007-11-15 22:14:46 +01:00
|
|
|
#endif /* USE_SSL */
|
2007-02-16 18:07:00 +01:00
|
|
|
|
2003-06-12 00:13:22 +02:00
|
|
|
/* End-of-list marker */
|
2001-10-25 07:50:21 +02:00
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
|
2001-10-25 07:50:21 +02:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-03-10 13:55:13 +01:00
|
|
|
static struct config_enum ConfigureNamesEnum[] =
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{"client_min_messages", PGC_USERSET, LOGGING_WHEN,
|
|
|
|
gettext_noop("Sets the message levels that are sent to the client."),
|
|
|
|
gettext_noop("Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, "
|
|
|
|
"DEBUG1, LOG, NOTICE, WARNING, and ERROR. Each level includes all the "
|
|
|
|
"levels that follow it. The later the level, the fewer messages are "
|
|
|
|
"sent.")
|
|
|
|
},
|
|
|
|
&client_min_messages,
|
|
|
|
NOTICE, message_level_options,NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"log_error_verbosity", PGC_SUSET, LOGGING_WHEN,
|
|
|
|
gettext_noop("Sets the verbosity of logged messages."),
|
|
|
|
gettext_noop("Valid values are \"terse\", \"default\", and \"verbose\".")
|
|
|
|
},
|
|
|
|
&Log_error_verbosity,
|
|
|
|
PGERROR_DEFAULT, log_error_verbosity_options, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"log_min_messages", PGC_SUSET, LOGGING_WHEN,
|
|
|
|
gettext_noop("Sets the message levels that are logged."),
|
|
|
|
gettext_noop("Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, "
|
|
|
|
"INFO, NOTICE, WARNING, ERROR, LOG, FATAL, and PANIC. Each level "
|
|
|
|
"includes all the levels that follow it.")
|
|
|
|
},
|
|
|
|
&log_min_messages,
|
|
|
|
WARNING, message_level_options, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"log_min_error_statement", PGC_SUSET, LOGGING_WHEN,
|
|
|
|
gettext_noop("Causes all statements generating error at or above this level to be logged."),
|
|
|
|
gettext_noop("All SQL statements that cause an error of the "
|
|
|
|
"specified level or a higher level are logged.")
|
|
|
|
},
|
|
|
|
&log_min_error_statement,
|
|
|
|
ERROR, message_level_options, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{"log_statement", PGC_SUSET, LOGGING_WHAT,
|
|
|
|
gettext_noop("Sets the type of statements logged."),
|
|
|
|
gettext_noop("Valid values are \"none\", \"ddl\", \"mod\", and \"all\".")
|
|
|
|
},
|
|
|
|
&log_statement,
|
|
|
|
LOGSTMT_NONE, log_statement_options, NULL, NULL
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* End-of-list marker */
|
|
|
|
{
|
|
|
|
{NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2004-07-11 02:18:45 +02:00
|
|
|
/******** end of options list ********/
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2004-02-03 18:34:04 +01:00
|
|
|
/*
|
|
|
|
* To allow continued support of obsolete names for GUC variables, we apply
|
|
|
|
* the following mappings to any unrecognized name. Note that an old name
|
|
|
|
* should be mapped to a new one only if the new variable has very similar
|
|
|
|
* semantics to the old.
|
|
|
|
*/
|
2004-08-29 07:07:03 +02:00
|
|
|
static const char *const map_old_guc_names[] = {
|
2004-02-03 18:34:04 +01:00
|
|
|
"sort_mem", "work_mem",
|
|
|
|
"vacuum_mem", "maintenance_work_mem",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2000-05-31 02:28:42 +02:00
|
|
|
/*
|
2002-05-17 03:19:19 +02:00
|
|
|
* Actual lookup of variables is done through this single, sorted array.
|
2000-05-31 02:28:42 +02:00
|
|
|
*/
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
static struct config_generic **guc_variables;
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
/* Current number of variables contained in the vector */
|
2004-08-29 07:07:03 +02:00
|
|
|
static int num_guc_variables;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
/* Vector capacity */
|
2004-08-29 07:07:03 +02:00
|
|
|
static int size_guc_variables;
|
2001-01-24 19:37:31 +01:00
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
static bool guc_dirty; /* TRUE if need to do commit/abort work */
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2003-04-25 21:45:10 +02:00
|
|
|
static bool reporting_enabled; /* TRUE to enable GUC_REPORT */
|
|
|
|
|
2007-09-03 02:39:26 +02:00
|
|
|
static int GUCNestLevel = 0; /* 1 when in main transaction */
|
|
|
|
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
static int guc_var_compare(const void *a, const void *b);
|
2004-02-03 18:34:04 +01:00
|
|
|
static int guc_name_compare(const char *namea, const char *nameb);
|
2007-09-11 02:06:42 +02:00
|
|
|
static void push_old_value(struct config_generic * gconf, GucAction action);
|
2003-07-04 18:41:22 +02:00
|
|
|
static void ReportGUCOption(struct config_generic * record);
|
2004-10-22 21:48:19 +02:00
|
|
|
static void ShowGUCConfigOption(const char *name, DestReceiver *dest);
|
|
|
|
static void ShowAllGUCConfig(DestReceiver *dest);
|
2006-07-27 10:30:41 +02:00
|
|
|
static char *_ShowOption(struct config_generic * record, bool use_units);
|
2007-11-15 22:14:46 +01:00
|
|
|
static bool is_newvalue_equal(struct config_generic * record, const char *newvalue);
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2004-07-06 01:14:14 +02:00
|
|
|
/*
|
|
|
|
* Some infrastructure for checking malloc/strdup/realloc calls
|
|
|
|
*/
|
|
|
|
static void *
|
|
|
|
guc_malloc(int elevel, size_t size)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
void *data;
|
2004-07-06 01:14:14 +02:00
|
|
|
|
|
|
|
data = malloc(size);
|
|
|
|
if (data == NULL)
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
|
|
|
errmsg("out of memory")));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
guc_realloc(int elevel, void *old, size_t size)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
void *data;
|
2004-07-06 01:14:14 +02:00
|
|
|
|
|
|
|
data = realloc(old, size);
|
|
|
|
if (data == NULL)
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
|
|
|
errmsg("out of memory")));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
guc_strdup(int elevel, const char *src)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
char *data;
|
2004-07-06 01:14:14 +02:00
|
|
|
|
|
|
|
data = strdup(src);
|
|
|
|
if (data == NULL)
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
|
|
|
errmsg("out of memory")));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
/*
|
|
|
|
* Support for assigning to a field of a string GUC item. Free the prior
|
|
|
|
* value if it's not referenced anywhere else in the item (including stacked
|
|
|
|
* states).
|
|
|
|
*/
|
|
|
|
static void
|
2006-08-14 04:27:27 +02:00
|
|
|
set_string_field(struct config_string * conf, char **field, char *newval)
|
2004-07-01 02:52:04 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
char *oldval = *field;
|
|
|
|
GucStack *stack;
|
2004-07-01 02:52:04 +02:00
|
|
|
|
|
|
|
/* Do the assignment */
|
|
|
|
*field = newval;
|
|
|
|
|
|
|
|
/* Exit if any duplicate references, or if old value was NULL anyway */
|
|
|
|
if (oldval == NULL ||
|
|
|
|
oldval == *(conf->variable) ||
|
|
|
|
oldval == conf->reset_val ||
|
2007-04-21 22:02:41 +02:00
|
|
|
oldval == conf->boot_val)
|
2004-07-01 02:52:04 +02:00
|
|
|
return;
|
|
|
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
if (oldval == stack->prior.stringval ||
|
|
|
|
oldval == stack->masked.stringval)
|
2004-07-01 02:52:04 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Not used anymore, so free it */
|
|
|
|
free(oldval);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Detect whether strval is referenced anywhere in a GUC string item
|
|
|
|
*/
|
|
|
|
static bool
|
2004-08-29 07:07:03 +02:00
|
|
|
string_field_used(struct config_string * conf, char *strval)
|
2004-07-01 02:52:04 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
GucStack *stack;
|
2004-07-01 02:52:04 +02:00
|
|
|
|
|
|
|
if (strval == *(conf->variable) ||
|
|
|
|
strval == conf->reset_val ||
|
2007-04-21 22:02:41 +02:00
|
|
|
strval == conf->boot_val)
|
2004-07-01 02:52:04 +02:00
|
|
|
return true;
|
|
|
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
if (strval == stack->prior.stringval ||
|
|
|
|
strval == stack->masked.stringval)
|
2004-07-01 02:52:04 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
/*
|
|
|
|
* Support for copying a variable's active value into a stack entry
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
set_stack_value(struct config_generic * gconf, union config_var_value * val)
|
|
|
|
{
|
|
|
|
switch (gconf->vartype)
|
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
|
|
|
val->boolval =
|
|
|
|
*((struct config_bool *) gconf)->variable;
|
|
|
|
break;
|
|
|
|
case PGC_INT:
|
|
|
|
val->intval =
|
|
|
|
*((struct config_int *) gconf)->variable;
|
|
|
|
break;
|
|
|
|
case PGC_REAL:
|
|
|
|
val->realval =
|
|
|
|
*((struct config_real *) gconf)->variable;
|
|
|
|
break;
|
|
|
|
case PGC_STRING:
|
|
|
|
/* we assume stringval is NULL if not valid */
|
|
|
|
set_string_field((struct config_string *) gconf,
|
|
|
|
&(val->stringval),
|
|
|
|
*((struct config_string *) gconf)->variable);
|
|
|
|
break;
|
2008-03-10 13:55:13 +01:00
|
|
|
case PGC_ENUM:
|
|
|
|
val->enumval =
|
|
|
|
*((struct config_enum *) gconf)->variable;
|
|
|
|
break;
|
2007-09-11 02:06:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Support for discarding a no-longer-needed value in a stack entry
|
|
|
|
*/
|
|
|
|
static void
|
2007-11-15 22:14:46 +01:00
|
|
|
discard_stack_value(struct config_generic * gconf, union config_var_value * val)
|
2007-09-11 02:06:42 +02:00
|
|
|
{
|
|
|
|
switch (gconf->vartype)
|
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
|
|
|
case PGC_INT:
|
|
|
|
case PGC_REAL:
|
2008-03-10 13:55:13 +01:00
|
|
|
case PGC_ENUM:
|
2007-09-11 02:06:42 +02:00
|
|
|
/* no need to do anything */
|
|
|
|
break;
|
|
|
|
case PGC_STRING:
|
|
|
|
set_string_field((struct config_string *) gconf,
|
|
|
|
&(val->stringval),
|
|
|
|
NULL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
/*
|
|
|
|
* Fetch the sorted array pointer (exported for help_config.c's use ONLY)
|
|
|
|
*/
|
2004-07-01 02:52:04 +02:00
|
|
|
struct config_generic **
|
|
|
|
get_guc_variables(void)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
|
|
|
return guc_variables;
|
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2000-05-31 02:28:42 +02:00
|
|
|
/*
|
2002-09-04 22:31:48 +02:00
|
|
|
* Build the sorted array. This is split out so that it could be
|
2002-05-17 03:19:19 +02:00
|
|
|
* re-executed after startup (eg, we could allow loadable modules to
|
|
|
|
* add vars, and then we'd need to re-sort).
|
2000-05-31 02:28:42 +02:00
|
|
|
*/
|
2003-07-04 18:41:22 +02:00
|
|
|
void
|
2002-05-17 03:19:19 +02:00
|
|
|
build_guc_variables(void)
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
int size_vars;
|
2002-05-17 03:19:19 +02:00
|
|
|
int num_vars = 0;
|
|
|
|
struct config_generic **guc_vars;
|
2001-03-22 05:01:46 +01:00
|
|
|
int i;
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; ConfigureNamesBool[i].gen.name; i++)
|
2001-06-13 00:54:06 +02:00
|
|
|
{
|
|
|
|
struct config_bool *conf = &ConfigureNamesBool[i];
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/* Rather than requiring vartype to be filled in by hand, do this: */
|
|
|
|
conf->gen.vartype = PGC_BOOL;
|
|
|
|
num_vars++;
|
2001-06-13 00:54:06 +02:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; ConfigureNamesInt[i].gen.name; i++)
|
2001-06-13 00:54:06 +02:00
|
|
|
{
|
|
|
|
struct config_int *conf = &ConfigureNamesInt[i];
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
conf->gen.vartype = PGC_INT;
|
|
|
|
num_vars++;
|
2001-06-13 00:54:06 +02:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; ConfigureNamesReal[i].gen.name; i++)
|
2001-06-13 00:54:06 +02:00
|
|
|
{
|
|
|
|
struct config_real *conf = &ConfigureNamesReal[i];
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
conf->gen.vartype = PGC_REAL;
|
|
|
|
num_vars++;
|
2001-06-13 00:54:06 +02:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; ConfigureNamesString[i].gen.name; i++)
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2001-06-13 00:54:06 +02:00
|
|
|
struct config_string *conf = &ConfigureNamesString[i];
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
conf->gen.vartype = PGC_STRING;
|
|
|
|
num_vars++;
|
2000-05-31 02:28:42 +02:00
|
|
|
}
|
|
|
|
|
2008-03-10 13:55:13 +01:00
|
|
|
for (i = 0; ConfigureNamesEnum[i].gen.name; i++)
|
|
|
|
{
|
|
|
|
struct config_enum *conf = &ConfigureNamesEnum[i];
|
|
|
|
|
|
|
|
conf->gen.vartype = PGC_ENUM;
|
|
|
|
num_vars++;
|
|
|
|
}
|
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
/*
|
|
|
|
* Create table with 20% slack
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
*/
|
|
|
|
size_vars = num_vars + num_vars / 4;
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
guc_vars = (struct config_generic **)
|
2004-07-06 01:14:14 +02:00
|
|
|
guc_malloc(FATAL, size_vars * sizeof(struct config_generic *));
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
num_vars = 0;
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; ConfigureNamesBool[i].gen.name; i++)
|
2002-09-04 22:31:48 +02:00
|
|
|
guc_vars[num_vars++] = &ConfigureNamesBool[i].gen;
|
2001-01-24 19:37:31 +01:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; ConfigureNamesInt[i].gen.name; i++)
|
2002-09-04 22:31:48 +02:00
|
|
|
guc_vars[num_vars++] = &ConfigureNamesInt[i].gen;
|
2001-01-24 19:37:31 +01:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; ConfigureNamesReal[i].gen.name; i++)
|
2002-09-04 22:31:48 +02:00
|
|
|
guc_vars[num_vars++] = &ConfigureNamesReal[i].gen;
|
2001-01-24 19:37:31 +01:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; ConfigureNamesString[i].gen.name; i++)
|
2002-09-04 22:31:48 +02:00
|
|
|
guc_vars[num_vars++] = &ConfigureNamesString[i].gen;
|
2001-01-24 19:37:31 +01:00
|
|
|
|
2008-03-10 13:55:13 +01:00
|
|
|
for (i = 0; ConfigureNamesEnum[i].gen.name; i++)
|
|
|
|
guc_vars[num_vars++] = &ConfigureNamesEnum[i].gen;
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
if (guc_variables)
|
|
|
|
free(guc_variables);
|
|
|
|
guc_variables = guc_vars;
|
|
|
|
num_guc_variables = num_vars;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
size_guc_variables = size_vars;
|
2004-08-29 07:07:03 +02:00
|
|
|
qsort((void *) guc_variables, num_guc_variables,
|
|
|
|
sizeof(struct config_generic *), guc_var_compare);
|
2000-05-31 02:28:42 +02:00
|
|
|
}
|
|
|
|
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
/*
|
|
|
|
* Add a new GUC variable to the list of known variables. The
|
|
|
|
* list is expanded if needed.
|
|
|
|
*/
|
2004-07-06 01:14:14 +02:00
|
|
|
static bool
|
2004-08-29 07:07:03 +02:00
|
|
|
add_guc_variable(struct config_generic * var, int elevel)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
if (num_guc_variables + 1 >= size_guc_variables)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
/*
|
|
|
|
* Increase the vector by 25%
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
*/
|
2004-08-29 07:07:03 +02:00
|
|
|
int size_vars = size_guc_variables + size_guc_variables / 4;
|
|
|
|
struct config_generic **guc_vars;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
if (size_vars == 0)
|
2004-07-06 01:14:14 +02:00
|
|
|
{
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
size_vars = 100;
|
2004-08-29 07:07:03 +02:00
|
|
|
guc_vars = (struct config_generic **)
|
|
|
|
guc_malloc(elevel, size_vars * sizeof(struct config_generic *));
|
2004-07-06 01:14:14 +02:00
|
|
|
}
|
|
|
|
else
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
guc_vars = (struct config_generic **)
|
|
|
|
guc_realloc(elevel, guc_variables, size_vars * sizeof(struct config_generic *));
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
}
|
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
if (guc_vars == NULL)
|
2004-07-06 01:14:14 +02:00
|
|
|
return false; /* out of memory */
|
|
|
|
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
guc_variables = guc_vars;
|
|
|
|
size_guc_variables = size_vars;
|
|
|
|
}
|
|
|
|
guc_variables[num_guc_variables++] = var;
|
2004-08-29 07:07:03 +02:00
|
|
|
qsort((void *) guc_variables, num_guc_variables,
|
|
|
|
sizeof(struct config_generic *), guc_var_compare);
|
2004-07-06 01:14:14 +02:00
|
|
|
return true;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2004-07-06 01:14:14 +02:00
|
|
|
* Create and add a placeholder variable. It's presumed to belong
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
* to a valid custom variable class at this point.
|
|
|
|
*/
|
2007-09-10 02:57:22 +02:00
|
|
|
static struct config_generic *
|
2004-07-06 01:14:14 +02:00
|
|
|
add_placeholder_variable(const char *name, int elevel)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
size_t sz = sizeof(struct config_string) + sizeof(char *);
|
|
|
|
struct config_string *var;
|
|
|
|
struct config_generic *gen;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
var = (struct config_string *) guc_malloc(elevel, sz);
|
|
|
|
if (var == NULL)
|
2004-07-06 01:14:14 +02:00
|
|
|
return NULL;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
memset(var, 0, sz);
|
2007-09-10 02:57:22 +02:00
|
|
|
gen = &var->gen;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
gen->name = guc_strdup(elevel, name);
|
|
|
|
if (gen->name == NULL)
|
2004-07-06 01:14:14 +02:00
|
|
|
{
|
|
|
|
free(var);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
gen->context = PGC_USERSET;
|
|
|
|
gen->group = CUSTOM_OPTIONS;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
gen->short_desc = "GUC placeholder variable";
|
2004-08-29 07:07:03 +02:00
|
|
|
gen->flags = GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_CUSTOM_PLACEHOLDER;
|
|
|
|
gen->vartype = PGC_STRING;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
/*
|
|
|
|
* The char* is allocated at the end of the struct since we have no
|
2007-11-15 22:14:46 +01:00
|
|
|
* 'static' place to point to. Note that the current value, as well as
|
|
|
|
* the boot and reset values, start out NULL.
|
2004-08-29 07:07:03 +02:00
|
|
|
*/
|
|
|
|
var->variable = (char **) (var + 1);
|
2004-07-06 01:14:14 +02:00
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
if (!add_guc_variable((struct config_generic *) var, elevel))
|
2004-07-06 01:14:14 +02:00
|
|
|
{
|
|
|
|
free((void *) gen->name);
|
|
|
|
free(var);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
return gen;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Detect whether the portion of "name" before dotPos matches any custom
|
|
|
|
* variable class name listed in custom_var_classes. The latter must be
|
|
|
|
* formatted the way that assign_custom_variable_classes does it, ie,
|
|
|
|
* no whitespace. NULL is valid for custom_var_classes.
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
is_custom_class(const char *name, int dotPos, const char *custom_var_classes)
|
|
|
|
{
|
|
|
|
bool result = false;
|
|
|
|
const char *ccs = custom_var_classes;
|
|
|
|
|
|
|
|
if (ccs != NULL)
|
|
|
|
{
|
|
|
|
const char *start = ccs;
|
|
|
|
|
|
|
|
for (;; ++ccs)
|
|
|
|
{
|
|
|
|
char c = *ccs;
|
|
|
|
|
|
|
|
if (c == '\0' || c == ',')
|
|
|
|
{
|
|
|
|
if (dotPos == ccs - start && strncmp(start, name, dotPos) == 0)
|
|
|
|
{
|
|
|
|
result = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (c == '\0')
|
|
|
|
break;
|
|
|
|
start = ccs + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
|
|
|
/*
|
2007-09-10 02:57:22 +02:00
|
|
|
* Look up option NAME. If it exists, return a pointer to its record,
|
|
|
|
* else return NULL. If create_placeholders is TRUE, we'll create a
|
|
|
|
* placeholder record for a valid-looking custom variable name.
|
2000-05-31 02:28:42 +02:00
|
|
|
*/
|
2002-05-17 03:19:19 +02:00
|
|
|
static struct config_generic *
|
2007-09-10 02:57:22 +02:00
|
|
|
find_option(const char *name, bool create_placeholders, int elevel)
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2002-05-17 03:19:19 +02:00
|
|
|
const char **key = &name;
|
|
|
|
struct config_generic **res;
|
2004-02-03 18:34:04 +01:00
|
|
|
int i;
|
2001-01-24 19:37:31 +01:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
Assert(name);
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* By equating const char ** with struct config_generic *, we are assuming
|
|
|
|
* the name field is first in config_generic.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
2002-09-04 22:31:48 +02:00
|
|
|
res = (struct config_generic **) bsearch((void *) &key,
|
|
|
|
(void *) guc_variables,
|
|
|
|
num_guc_variables,
|
2005-10-15 04:49:52 +02:00
|
|
|
sizeof(struct config_generic *),
|
2002-09-04 22:31:48 +02:00
|
|
|
guc_var_compare);
|
2002-05-17 03:19:19 +02:00
|
|
|
if (res)
|
|
|
|
return *res;
|
2004-02-03 18:34:04 +01:00
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* See if the name is an obsolete name for a variable. We assume that the
|
|
|
|
* set of supported old names is short enough that a brute-force search is
|
|
|
|
* the best way.
|
2004-02-03 18:34:04 +01:00
|
|
|
*/
|
|
|
|
for (i = 0; map_old_guc_names[i] != NULL; i += 2)
|
|
|
|
{
|
|
|
|
if (guc_name_compare(name, map_old_guc_names[i]) == 0)
|
2007-09-10 02:57:22 +02:00
|
|
|
return find_option(map_old_guc_names[i + 1], false, elevel);
|
2004-02-03 18:34:04 +01:00
|
|
|
}
|
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
if (create_placeholders)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Check if the name is qualified, and if so, check if the qualifier
|
|
|
|
* matches any custom variable class. If so, add a placeholder.
|
|
|
|
*/
|
|
|
|
const char *dot = strchr(name, GUC_QUALIFIER_SEPARATOR);
|
|
|
|
|
|
|
|
if (dot != NULL &&
|
|
|
|
is_custom_class(name, dot - name, custom_variable_classes))
|
|
|
|
return add_placeholder_variable(name, elevel);
|
|
|
|
}
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2004-02-03 18:34:04 +01:00
|
|
|
/* Unknown name */
|
2002-05-17 03:19:19 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
2002-05-17 03:19:19 +02:00
|
|
|
* comparator for qsorting and bsearching guc_variables array
|
2000-05-31 02:28:42 +02:00
|
|
|
*/
|
2002-05-17 03:19:19 +02:00
|
|
|
static int
|
|
|
|
guc_var_compare(const void *a, const void *b)
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2002-05-17 03:19:19 +02:00
|
|
|
struct config_generic *confa = *(struct config_generic **) a;
|
|
|
|
struct config_generic *confb = *(struct config_generic **) b;
|
2001-01-24 19:37:31 +01:00
|
|
|
|
2004-02-03 18:34:04 +01:00
|
|
|
return guc_name_compare(confa->name, confb->name);
|
|
|
|
}
|
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
/*
|
|
|
|
* the bare comparison function for GUC names
|
|
|
|
*/
|
2004-02-03 18:34:04 +01:00
|
|
|
static int
|
|
|
|
guc_name_compare(const char *namea, const char *nameb)
|
|
|
|
{
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* The temptation to use strcasecmp() here must be resisted, because the
|
|
|
|
* array ordering has to remain stable across setlocale() calls. So, build
|
|
|
|
* our own with a simple ASCII-only downcasing.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
2002-05-17 22:32:29 +02:00
|
|
|
while (*namea && *nameb)
|
|
|
|
{
|
|
|
|
char cha = *namea++;
|
|
|
|
char chb = *nameb++;
|
|
|
|
|
|
|
|
if (cha >= 'A' && cha <= 'Z')
|
|
|
|
cha += 'a' - 'A';
|
|
|
|
if (chb >= 'A' && chb <= 'Z')
|
|
|
|
chb += 'a' - 'A';
|
|
|
|
if (cha != chb)
|
|
|
|
return cha - chb;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2002-05-17 22:32:29 +02:00
|
|
|
if (*namea)
|
|
|
|
return 1; /* a is longer */
|
|
|
|
if (*nameb)
|
|
|
|
return -1; /* b is longer */
|
|
|
|
return 0;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
2002-05-17 03:19:19 +02:00
|
|
|
* Initialize GUC options during program startup.
|
2004-10-08 03:36:36 +02:00
|
|
|
*
|
|
|
|
* Note that we cannot read the config file yet, since we have not yet
|
|
|
|
* processed command-line switches.
|
2000-05-31 02:28:42 +02:00
|
|
|
*/
|
2002-05-17 03:19:19 +02:00
|
|
|
void
|
|
|
|
InitializeGUCOptions(void)
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2002-05-17 03:19:19 +02:00
|
|
|
int i;
|
|
|
|
char *env;
|
2006-10-07 21:25:29 +02:00
|
|
|
long stack_rlimit;
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2007-08-04 21:29:25 +02:00
|
|
|
/*
|
2007-11-15 22:14:46 +01:00
|
|
|
* Before log_line_prefix could possibly receive a nonempty setting, make
|
|
|
|
* sure that timezone processing is minimally alive (see elog.c).
|
2007-08-04 21:29:25 +02:00
|
|
|
*/
|
|
|
|
pg_timezone_pre_initialize();
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
|
|
|
* Build sorted array of all GUC variables.
|
|
|
|
*/
|
|
|
|
build_guc_variables();
|
2002-02-23 02:31:37 +01:00
|
|
|
|
2000-06-23 00:31:24 +02:00
|
|
|
/*
|
2002-05-17 03:19:19 +02:00
|
|
|
* Load all variables with their compiled-in defaults, and initialize
|
|
|
|
* status fields as needed.
|
2000-06-23 00:31:24 +02:00
|
|
|
*/
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; i < num_guc_variables; i++)
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2002-05-17 03:19:19 +02:00
|
|
|
struct config_generic *gconf = guc_variables[i];
|
2001-10-25 07:50:21 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
gconf->status = 0;
|
|
|
|
gconf->reset_source = PGC_S_DEFAULT;
|
|
|
|
gconf->source = PGC_S_DEFAULT;
|
2004-07-01 02:52:04 +02:00
|
|
|
gconf->stack = NULL;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
switch (gconf->vartype)
|
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
|
|
|
struct config_bool *conf = (struct config_bool *) gconf;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
if (conf->assign_hook)
|
2007-04-21 22:02:41 +02:00
|
|
|
if (!(*conf->assign_hook) (conf->boot_val, true,
|
2006-08-14 04:27:27 +02:00
|
|
|
PGC_S_DEFAULT))
|
|
|
|
elog(FATAL, "failed to initialize %s to %d",
|
2007-04-21 22:02:41 +02:00
|
|
|
conf->gen.name, (int) conf->boot_val);
|
|
|
|
*conf->variable = conf->reset_val = conf->boot_val;
|
2002-09-04 22:31:48 +02:00
|
|
|
break;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
case PGC_INT:
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
|
|
|
struct config_int *conf = (struct config_int *) gconf;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2007-04-21 22:02:41 +02:00
|
|
|
Assert(conf->boot_val >= conf->min);
|
|
|
|
Assert(conf->boot_val <= conf->max);
|
2006-08-14 04:27:27 +02:00
|
|
|
if (conf->assign_hook)
|
2007-04-21 22:02:41 +02:00
|
|
|
if (!(*conf->assign_hook) (conf->boot_val, true,
|
2006-08-14 04:27:27 +02:00
|
|
|
PGC_S_DEFAULT))
|
|
|
|
elog(FATAL, "failed to initialize %s to %d",
|
2007-04-21 22:02:41 +02:00
|
|
|
conf->gen.name, conf->boot_val);
|
2007-05-04 03:13:45 +02:00
|
|
|
*conf->variable = conf->reset_val = conf->boot_val;
|
2002-09-04 22:31:48 +02:00
|
|
|
break;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
case PGC_REAL:
|
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
struct config_real *conf = (struct config_real *) gconf;
|
|
|
|
|
2007-04-21 22:02:41 +02:00
|
|
|
Assert(conf->boot_val >= conf->min);
|
|
|
|
Assert(conf->boot_val <= conf->max);
|
2006-08-14 04:27:27 +02:00
|
|
|
if (conf->assign_hook)
|
2007-04-21 22:02:41 +02:00
|
|
|
if (!(*conf->assign_hook) (conf->boot_val, true,
|
2006-08-14 04:27:27 +02:00
|
|
|
PGC_S_DEFAULT))
|
|
|
|
elog(FATAL, "failed to initialize %s to %g",
|
2007-04-21 22:02:41 +02:00
|
|
|
conf->gen.name, conf->boot_val);
|
2007-05-04 03:13:45 +02:00
|
|
|
*conf->variable = conf->reset_val = conf->boot_val;
|
2002-05-17 03:19:19 +02:00
|
|
|
break;
|
|
|
|
}
|
2002-09-04 22:31:48 +02:00
|
|
|
case PGC_STRING:
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
struct config_string *conf = (struct config_string *) gconf;
|
|
|
|
char *str;
|
|
|
|
|
|
|
|
*conf->variable = NULL;
|
|
|
|
conf->reset_val = NULL;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
if (conf->boot_val == NULL)
|
2006-08-14 04:27:27 +02:00
|
|
|
{
|
2007-09-10 02:57:22 +02:00
|
|
|
/* leave the value NULL, do not call assign hook */
|
2002-09-04 22:31:48 +02:00
|
|
|
break;
|
2006-08-14 04:27:27 +02:00
|
|
|
}
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2004-07-06 01:14:14 +02:00
|
|
|
str = guc_strdup(FATAL, conf->boot_val);
|
2002-09-04 22:31:48 +02:00
|
|
|
conf->reset_val = str;
|
|
|
|
|
|
|
|
if (conf->assign_hook)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
const char *newstr;
|
|
|
|
|
2004-01-19 20:04:40 +01:00
|
|
|
newstr = (*conf->assign_hook) (str, true,
|
|
|
|
PGC_S_DEFAULT);
|
2002-09-04 22:31:48 +02:00
|
|
|
if (newstr == NULL)
|
2006-08-14 04:27:27 +02:00
|
|
|
{
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(FATAL, "failed to initialize %s to \"%s\"",
|
|
|
|
conf->gen.name, str);
|
2006-08-14 04:27:27 +02:00
|
|
|
}
|
2002-09-04 22:31:48 +02:00
|
|
|
else if (newstr != str)
|
|
|
|
{
|
|
|
|
free(str);
|
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* See notes in set_config_option about casting
|
2002-09-04 22:31:48 +02:00
|
|
|
*/
|
|
|
|
str = (char *) newstr;
|
|
|
|
conf->reset_val = str;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2002-09-04 22:31:48 +02:00
|
|
|
*conf->variable = str;
|
|
|
|
break;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2008-03-10 13:55:13 +01:00
|
|
|
case PGC_ENUM:
|
|
|
|
{
|
|
|
|
struct config_enum *conf = (struct config_enum *) gconf;
|
|
|
|
|
|
|
|
if (conf->assign_hook)
|
|
|
|
if (!(*conf->assign_hook) (conf->boot_val, true,
|
|
|
|
PGC_S_DEFAULT))
|
|
|
|
elog(FATAL, "failed to initialize %s to %d",
|
|
|
|
conf->gen.name, conf->boot_val);
|
|
|
|
*conf->variable = conf->reset_val = conf->boot_val;
|
|
|
|
break;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
guc_dirty = false;
|
|
|
|
|
2003-04-25 21:45:10 +02:00
|
|
|
reporting_enabled = false;
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
2003-01-10 23:03:30 +01:00
|
|
|
* Prevent any attempt to override the transaction modes from
|
2002-05-17 03:19:19 +02:00
|
|
|
* non-interactive sources.
|
|
|
|
*/
|
2003-01-10 23:03:30 +01:00
|
|
|
SetConfigOption("transaction_isolation", "default",
|
|
|
|
PGC_POSTMASTER, PGC_S_OVERRIDE);
|
|
|
|
SetConfigOption("transaction_read_only", "no",
|
2002-05-17 03:19:19 +02:00
|
|
|
PGC_POSTMASTER, PGC_S_OVERRIDE);
|
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* For historical reasons, some GUC parameters can receive defaults from
|
2007-11-15 22:14:46 +01:00
|
|
|
* environment variables. Process those settings. NB: if you add or
|
2007-09-10 02:57:22 +02:00
|
|
|
* remove anything here, see also ProcessConfigFile().
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
env = getenv("PGPORT");
|
|
|
|
if (env != NULL)
|
|
|
|
SetConfigOption("port", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
|
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
env = getenv("PGDATESTYLE");
|
|
|
|
if (env != NULL)
|
2002-05-17 03:19:19 +02:00
|
|
|
SetConfigOption("datestyle", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
|
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
env = getenv("PGCLIENTENCODING");
|
|
|
|
if (env != NULL)
|
2002-05-17 03:19:19 +02:00
|
|
|
SetConfigOption("client_encoding", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
|
2006-10-07 21:25:29 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* rlimit isn't exactly an "environment variable", but it behaves about
|
|
|
|
* the same. If we can identify the platform stack depth rlimit, increase
|
|
|
|
* default stack depth setting up to whatever is safe (but at most 2MB).
|
|
|
|
*/
|
|
|
|
stack_rlimit = get_stack_depth_rlimit();
|
|
|
|
if (stack_rlimit > 0)
|
|
|
|
{
|
2007-11-15 22:14:46 +01:00
|
|
|
int new_limit = (stack_rlimit - STACK_DEPTH_SLOP) / 1024L;
|
2006-10-07 21:25:29 +02:00
|
|
|
|
|
|
|
if (new_limit > 100)
|
|
|
|
{
|
2007-11-15 22:14:46 +01:00
|
|
|
char limbuf[16];
|
2006-10-07 21:25:29 +02:00
|
|
|
|
|
|
|
new_limit = Min(new_limit, 2048);
|
|
|
|
sprintf(limbuf, "%d", new_limit);
|
|
|
|
SetConfigOption("max_stack_depth", limbuf,
|
|
|
|
PGC_POSTMASTER, PGC_S_ENV_VAR);
|
|
|
|
}
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-08 03:36:36 +02:00
|
|
|
/*
|
|
|
|
* Select the configuration files and data directory to be used, and
|
|
|
|
* do the initial read of postgresql.conf.
|
|
|
|
*
|
|
|
|
* This is called after processing command-line switches.
|
|
|
|
* userDoption is the -D switch value if any (NULL if unspecified).
|
|
|
|
* progname is just for use in error messages.
|
|
|
|
*
|
|
|
|
* Returns true on success; on failure, prints a suitable error message
|
|
|
|
* to stderr and returns false.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
SelectConfigFiles(const char *userDoption, const char *progname)
|
|
|
|
{
|
2004-10-10 01:13:22 +02:00
|
|
|
char *configdir;
|
|
|
|
char *fname;
|
2004-10-08 03:36:36 +02:00
|
|
|
struct stat stat_buf;
|
|
|
|
|
2004-10-10 01:13:22 +02:00
|
|
|
/* configdir is -D option, or $PGDATA if no -D */
|
|
|
|
if (userDoption)
|
|
|
|
configdir = make_absolute_path(userDoption);
|
|
|
|
else
|
|
|
|
configdir = make_absolute_path(getenv("PGDATA"));
|
2004-10-08 03:36:36 +02:00
|
|
|
|
|
|
|
/*
|
2004-10-10 01:13:22 +02:00
|
|
|
* Find the configuration file: if config_file was specified on the
|
2005-10-15 04:49:52 +02:00
|
|
|
* command line, use it, else use configdir/postgresql.conf. In any case
|
|
|
|
* ensure the result is an absolute path, so that it will be interpreted
|
|
|
|
* the same way by future backends.
|
2004-10-08 03:36:36 +02:00
|
|
|
*/
|
2004-10-10 01:13:22 +02:00
|
|
|
if (ConfigFileName)
|
|
|
|
fname = make_absolute_path(ConfigFileName);
|
2005-05-27 20:33:30 +02:00
|
|
|
else if (configdir)
|
|
|
|
{
|
|
|
|
fname = guc_malloc(FATAL,
|
|
|
|
strlen(configdir) + strlen(CONFIG_FILENAME) + 2);
|
|
|
|
sprintf(fname, "%s/%s", configdir, CONFIG_FILENAME);
|
|
|
|
}
|
|
|
|
else
|
2004-10-08 03:36:36 +02:00
|
|
|
{
|
2004-10-10 01:13:22 +02:00
|
|
|
write_stderr("%s does not know where to find the server configuration file.\n"
|
2004-10-12 23:54:45 +02:00
|
|
|
"You must specify the --config-file or -D invocation "
|
2004-10-10 01:13:22 +02:00
|
|
|
"option or set the PGDATA environment variable.\n",
|
|
|
|
progname);
|
|
|
|
return false;
|
2004-10-08 03:36:36 +02:00
|
|
|
}
|
|
|
|
|
2004-10-10 01:13:22 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Set the ConfigFileName GUC variable to its final value, ensuring that
|
|
|
|
* it can't be overridden later.
|
2004-10-10 01:13:22 +02:00
|
|
|
*/
|
|
|
|
SetConfigOption("config_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
|
|
|
|
free(fname);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now read the config file for the first time.
|
|
|
|
*/
|
2004-10-08 03:36:36 +02:00
|
|
|
if (stat(ConfigFileName, &stat_buf) != 0)
|
|
|
|
{
|
2004-10-10 01:13:22 +02:00
|
|
|
write_stderr("%s cannot access the server configuration file \"%s\": %s\n",
|
2004-10-08 03:36:36 +02:00
|
|
|
progname, ConfigFileName, strerror(errno));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
ProcessConfigFile(PGC_POSTMASTER);
|
|
|
|
|
|
|
|
/*
|
2004-10-10 01:13:22 +02:00
|
|
|
* If the data_directory GUC variable has been set, use that as DataDir;
|
|
|
|
* otherwise use configdir if set; else punt.
|
2004-10-08 03:36:36 +02:00
|
|
|
*
|
2005-11-22 19:17:34 +01:00
|
|
|
* Note: SetDataDir will copy and absolute-ize its argument, so we don't
|
|
|
|
* have to.
|
2004-10-08 03:36:36 +02:00
|
|
|
*/
|
2004-10-10 01:13:22 +02:00
|
|
|
if (data_directory)
|
|
|
|
SetDataDir(data_directory);
|
|
|
|
else if (configdir)
|
|
|
|
SetDataDir(configdir);
|
2004-10-08 03:36:36 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
write_stderr("%s does not know where to find the database system data.\n"
|
2004-10-10 01:13:22 +02:00
|
|
|
"This can be specified as \"data_directory\" in \"%s\", "
|
|
|
|
"or by the -D invocation option, or by the "
|
|
|
|
"PGDATA environment variable.\n",
|
|
|
|
progname, ConfigFileName);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reflect the final DataDir value back into the data_directory GUC var.
|
|
|
|
* (If you are wondering why we don't just make them a single variable,
|
|
|
|
* it's because the EXEC_BACKEND case needs DataDir to be transmitted to
|
2005-10-15 04:49:52 +02:00
|
|
|
* child backends specially. XXX is that still true? Given that we now
|
|
|
|
* chdir to DataDir, EXEC_BACKEND can read the config file without knowing
|
|
|
|
* DataDir in advance.)
|
2004-10-10 01:13:22 +02:00
|
|
|
*/
|
|
|
|
SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Figure out where pg_hba.conf is, and make sure the path is absolute.
|
|
|
|
*/
|
|
|
|
if (HbaFileName)
|
|
|
|
fname = make_absolute_path(HbaFileName);
|
2005-05-27 20:33:30 +02:00
|
|
|
else if (configdir)
|
|
|
|
{
|
|
|
|
fname = guc_malloc(FATAL,
|
|
|
|
strlen(configdir) + strlen(HBA_FILENAME) + 2);
|
|
|
|
sprintf(fname, "%s/%s", configdir, HBA_FILENAME);
|
|
|
|
}
|
|
|
|
else
|
2004-10-10 01:13:22 +02:00
|
|
|
{
|
|
|
|
write_stderr("%s does not know where to find the \"hba\" configuration file.\n"
|
|
|
|
"This can be specified as \"hba_file\" in \"%s\", "
|
|
|
|
"or by the -D invocation option, or by the "
|
|
|
|
"PGDATA environment variable.\n",
|
2004-10-08 03:36:36 +02:00
|
|
|
progname, ConfigFileName);
|
|
|
|
return false;
|
|
|
|
}
|
2004-10-10 01:13:22 +02:00
|
|
|
SetConfigOption("hba_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
|
|
|
|
free(fname);
|
2004-10-08 03:36:36 +02:00
|
|
|
|
|
|
|
/*
|
2004-10-10 01:13:22 +02:00
|
|
|
* Likewise for pg_ident.conf.
|
2004-10-08 03:36:36 +02:00
|
|
|
*/
|
2004-10-10 01:13:22 +02:00
|
|
|
if (IdentFileName)
|
|
|
|
fname = make_absolute_path(IdentFileName);
|
2005-05-27 20:33:30 +02:00
|
|
|
else if (configdir)
|
|
|
|
{
|
|
|
|
fname = guc_malloc(FATAL,
|
|
|
|
strlen(configdir) + strlen(IDENT_FILENAME) + 2);
|
|
|
|
sprintf(fname, "%s/%s", configdir, IDENT_FILENAME);
|
|
|
|
}
|
|
|
|
else
|
2004-10-10 01:13:22 +02:00
|
|
|
{
|
|
|
|
write_stderr("%s does not know where to find the \"ident\" configuration file.\n"
|
|
|
|
"This can be specified as \"ident_file\" in \"%s\", "
|
|
|
|
"or by the -D invocation option, or by the "
|
|
|
|
"PGDATA environment variable.\n",
|
|
|
|
progname, ConfigFileName);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
SetConfigOption("ident_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
|
|
|
|
free(fname);
|
|
|
|
|
|
|
|
free(configdir);
|
2004-10-08 03:36:36 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
|
|
|
* Reset all options to their saved default values (implements RESET ALL)
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ResetAllOptions(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < num_guc_variables; i++)
|
|
|
|
{
|
|
|
|
struct config_generic *gconf = guc_variables[i];
|
|
|
|
|
|
|
|
/* Don't reset non-SET-able values */
|
2003-07-09 08:47:34 +02:00
|
|
|
if (gconf->context != PGC_SUSET &&
|
|
|
|
gconf->context != PGC_USERSET)
|
2002-05-17 03:19:19 +02:00
|
|
|
continue;
|
|
|
|
/* Don't reset if special exclusion from RESET ALL */
|
|
|
|
if (gconf->flags & GUC_NO_RESET_ALL)
|
|
|
|
continue;
|
|
|
|
/* No need to reset if wasn't SET */
|
|
|
|
if (gconf->source <= PGC_S_OVERRIDE)
|
|
|
|
continue;
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
/* Save old value to support transaction abort */
|
2007-09-11 02:06:42 +02:00
|
|
|
push_old_value(gconf, GUC_ACTION_SET);
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
switch (gconf->vartype)
|
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
|
|
|
struct config_bool *conf = (struct config_bool *) gconf;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
if (conf->assign_hook)
|
2004-01-19 20:04:40 +01:00
|
|
|
if (!(*conf->assign_hook) (conf->reset_val, true,
|
|
|
|
PGC_S_SESSION))
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(ERROR, "failed to reset %s", conf->gen.name);
|
2002-09-04 22:31:48 +02:00
|
|
|
*conf->variable = conf->reset_val;
|
|
|
|
conf->gen.source = conf->gen.reset_source;
|
|
|
|
break;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
case PGC_INT:
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
|
|
|
struct config_int *conf = (struct config_int *) gconf;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
if (conf->assign_hook)
|
2004-01-19 20:04:40 +01:00
|
|
|
if (!(*conf->assign_hook) (conf->reset_val, true,
|
|
|
|
PGC_S_SESSION))
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(ERROR, "failed to reset %s", conf->gen.name);
|
2002-09-04 22:31:48 +02:00
|
|
|
*conf->variable = conf->reset_val;
|
|
|
|
conf->gen.source = conf->gen.reset_source;
|
|
|
|
break;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
case PGC_REAL:
|
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
struct config_real *conf = (struct config_real *) gconf;
|
|
|
|
|
|
|
|
if (conf->assign_hook)
|
2004-01-19 20:04:40 +01:00
|
|
|
if (!(*conf->assign_hook) (conf->reset_val, true,
|
|
|
|
PGC_S_SESSION))
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(ERROR, "failed to reset %s", conf->gen.name);
|
2002-09-04 22:31:48 +02:00
|
|
|
*conf->variable = conf->reset_val;
|
|
|
|
conf->gen.source = conf->gen.reset_source;
|
2002-05-17 03:19:19 +02:00
|
|
|
break;
|
|
|
|
}
|
2002-09-04 22:31:48 +02:00
|
|
|
case PGC_STRING:
|
|
|
|
{
|
|
|
|
struct config_string *conf = (struct config_string *) gconf;
|
|
|
|
char *str;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
/* We need not strdup here */
|
|
|
|
str = conf->reset_val;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
if (conf->assign_hook && str)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
const char *newstr;
|
|
|
|
|
2004-01-19 20:04:40 +01:00
|
|
|
newstr = (*conf->assign_hook) (str, true,
|
|
|
|
PGC_S_SESSION);
|
2002-09-04 22:31:48 +02:00
|
|
|
if (newstr == NULL)
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(ERROR, "failed to reset %s", conf->gen.name);
|
2002-09-04 22:31:48 +02:00
|
|
|
else if (newstr != str)
|
|
|
|
{
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* See notes in set_config_option about casting
|
2002-09-04 22:31:48 +02:00
|
|
|
*/
|
|
|
|
str = (char *) newstr;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
set_string_field(conf, conf->variable, str);
|
2002-09-04 22:31:48 +02:00
|
|
|
conf->gen.source = conf->gen.reset_source;
|
|
|
|
break;
|
|
|
|
}
|
2008-03-10 13:55:13 +01:00
|
|
|
case PGC_ENUM:
|
|
|
|
{
|
|
|
|
struct config_enum *conf = (struct config_enum *) gconf;
|
|
|
|
|
|
|
|
if (conf->assign_hook)
|
|
|
|
if (!(*conf->assign_hook) (conf->reset_val, true,
|
|
|
|
PGC_S_SESSION))
|
|
|
|
elog(ERROR, "failed to reset %s", conf->gen.name);
|
|
|
|
*conf->variable = conf->reset_val;
|
|
|
|
conf->gen.source = conf->gen.reset_source;
|
|
|
|
break;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2003-04-25 21:45:10 +02:00
|
|
|
|
|
|
|
if (gconf->flags & GUC_REPORT)
|
|
|
|
ReportGUCOption(gconf);
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2004-07-01 02:52:04 +02:00
|
|
|
* push_old_value
|
2007-09-11 02:06:42 +02:00
|
|
|
* Push previous state during transactional assignment to a GUC variable.
|
2004-07-01 02:52:04 +02:00
|
|
|
*/
|
|
|
|
static void
|
2007-09-11 02:06:42 +02:00
|
|
|
push_old_value(struct config_generic * gconf, GucAction action)
|
2004-07-01 02:52:04 +02:00
|
|
|
{
|
|
|
|
GucStack *stack;
|
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
/* If we're not inside a nest level, do nothing */
|
2007-09-03 02:39:26 +02:00
|
|
|
if (GUCNestLevel == 0)
|
2004-07-01 02:52:04 +02:00
|
|
|
return;
|
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
/* Do we already have a stack entry of the current nest level? */
|
|
|
|
stack = gconf->stack;
|
|
|
|
if (stack && stack->nest_level >= GUCNestLevel)
|
2004-07-01 02:52:04 +02:00
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
/* Yes, so adjust its state if necessary */
|
|
|
|
Assert(stack->nest_level == GUCNestLevel);
|
|
|
|
switch (action)
|
2004-07-01 02:52:04 +02:00
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
case GUC_ACTION_SET:
|
|
|
|
/* SET overrides any prior action at same nest level */
|
|
|
|
if (stack->state == GUC_SET_LOCAL)
|
|
|
|
{
|
|
|
|
/* must discard old masked value */
|
|
|
|
discard_stack_value(gconf, &stack->masked);
|
|
|
|
}
|
|
|
|
stack->state = GUC_SET;
|
2004-07-01 02:52:04 +02:00
|
|
|
break;
|
2007-09-11 02:06:42 +02:00
|
|
|
case GUC_ACTION_LOCAL:
|
|
|
|
if (stack->state == GUC_SET)
|
|
|
|
{
|
|
|
|
/* SET followed by SET LOCAL, remember SET's value */
|
|
|
|
set_stack_value(gconf, &stack->masked);
|
|
|
|
stack->state = GUC_SET_LOCAL;
|
|
|
|
}
|
|
|
|
/* in all other cases, no change to stack entry */
|
2004-07-01 02:52:04 +02:00
|
|
|
break;
|
2007-09-11 02:06:42 +02:00
|
|
|
case GUC_ACTION_SAVE:
|
|
|
|
/* Could only have a prior SAVE of same variable */
|
|
|
|
Assert(stack->state == GUC_SAVE);
|
2004-07-01 02:52:04 +02:00
|
|
|
break;
|
|
|
|
}
|
2007-09-11 02:06:42 +02:00
|
|
|
Assert(guc_dirty); /* must be set already */
|
|
|
|
return;
|
|
|
|
}
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
/*
|
|
|
|
* Push a new stack entry
|
|
|
|
*
|
|
|
|
* We keep all the stack entries in TopTransactionContext for simplicity.
|
|
|
|
*/
|
|
|
|
stack = (GucStack *) MemoryContextAllocZero(TopTransactionContext,
|
|
|
|
sizeof(GucStack));
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
stack->prev = gconf->stack;
|
|
|
|
stack->nest_level = GUCNestLevel;
|
|
|
|
switch (action)
|
|
|
|
{
|
|
|
|
case GUC_ACTION_SET:
|
|
|
|
stack->state = GUC_SET;
|
|
|
|
break;
|
|
|
|
case GUC_ACTION_LOCAL:
|
|
|
|
stack->state = GUC_LOCAL;
|
|
|
|
break;
|
|
|
|
case GUC_ACTION_SAVE:
|
|
|
|
stack->state = GUC_SAVE;
|
|
|
|
break;
|
2004-07-01 02:52:04 +02:00
|
|
|
}
|
2007-09-11 02:06:42 +02:00
|
|
|
stack->source = gconf->source;
|
|
|
|
set_stack_value(gconf, &stack->prior);
|
|
|
|
|
|
|
|
gconf->stack = stack;
|
|
|
|
|
|
|
|
/* Ensure we remember to pop at end of xact */
|
|
|
|
guc_dirty = true;
|
2004-07-01 02:52:04 +02:00
|
|
|
}
|
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
|
2007-03-13 15:32:25 +01:00
|
|
|
/*
|
2007-09-03 02:39:26 +02:00
|
|
|
* Do GUC processing at main transaction start.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
|
|
|
void
|
2007-09-03 02:39:26 +02:00
|
|
|
AtStart_GUC(void)
|
|
|
|
{
|
|
|
|
/*
|
2007-11-15 22:14:46 +01:00
|
|
|
* The nest level should be 0 between transactions; if it isn't, somebody
|
|
|
|
* didn't call AtEOXact_GUC, or called it with the wrong nestLevel. We
|
|
|
|
* throw a warning but make no other effort to clean up.
|
2007-09-03 02:39:26 +02:00
|
|
|
*/
|
|
|
|
if (GUCNestLevel != 0)
|
|
|
|
elog(WARNING, "GUC nest level = %d at transaction start",
|
|
|
|
GUCNestLevel);
|
|
|
|
GUCNestLevel = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Enter a new nesting level for GUC values. This is called at subtransaction
|
2007-11-15 22:14:46 +01:00
|
|
|
* start and when entering a function that has proconfig settings. NOTE that
|
2007-09-03 02:39:26 +02:00
|
|
|
* we must not risk error here, else subtransaction start will be unhappy.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
NewGUCNestLevel(void)
|
|
|
|
{
|
|
|
|
return ++GUCNestLevel;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Do GUC processing at transaction or subtransaction commit or abort, or
|
|
|
|
* when exiting a function that has proconfig settings. (The name is thus
|
|
|
|
* a bit of a misnomer; perhaps it should be ExitGUCNestLevel or some such.)
|
|
|
|
* During abort, we discard all GUC settings that were applied at nesting
|
|
|
|
* levels >= nestLevel. nestLevel == 1 corresponds to the main transaction.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
AtEOXact_GUC(bool isCommit, int nestLevel)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
bool still_dirty;
|
2002-05-17 03:19:19 +02:00
|
|
|
int i;
|
|
|
|
|
2007-09-03 02:39:26 +02:00
|
|
|
Assert(nestLevel > 0 && nestLevel <= GUCNestLevel);
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/* Quick exit if nothing's changed in this transaction */
|
|
|
|
if (!guc_dirty)
|
2007-09-03 02:39:26 +02:00
|
|
|
{
|
|
|
|
GUCNestLevel = nestLevel - 1;
|
2002-05-17 03:19:19 +02:00
|
|
|
return;
|
2007-09-03 02:39:26 +02:00
|
|
|
}
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
still_dirty = false;
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; i < num_guc_variables; i++)
|
|
|
|
{
|
|
|
|
struct config_generic *gconf = guc_variables[i];
|
2007-09-11 02:06:42 +02:00
|
|
|
GucStack *stack;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
/*
|
2007-11-15 22:14:46 +01:00
|
|
|
* Process and pop each stack entry within the nest level. To
|
|
|
|
* simplify fmgr_security_definer(), we allow failure exit from a
|
|
|
|
* function-with-SET-options to be recovered at the surrounding
|
2007-09-11 02:06:42 +02:00
|
|
|
* transaction or subtransaction abort; so there could be more than
|
|
|
|
* one stack entry to pop.
|
2004-07-01 02:52:04 +02:00
|
|
|
*/
|
2007-09-11 02:06:42 +02:00
|
|
|
while ((stack = gconf->stack) != NULL &&
|
|
|
|
stack->nest_level >= nestLevel)
|
2004-07-01 02:52:04 +02:00
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
GucStack *prev = stack->prev;
|
|
|
|
bool restorePrior = false;
|
|
|
|
bool restoreMasked = false;
|
|
|
|
bool changed;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
/*
|
|
|
|
* In this next bit, if we don't set either restorePrior or
|
|
|
|
* restoreMasked, we must "discard" any unwanted fields of the
|
|
|
|
* stack entries to avoid leaking memory. If we do set one of
|
|
|
|
* those flags, unused fields will be cleaned up after restoring.
|
|
|
|
*/
|
2007-11-15 22:14:46 +01:00
|
|
|
if (!isCommit) /* if abort, always restore prior value */
|
2007-09-11 02:06:42 +02:00
|
|
|
restorePrior = true;
|
|
|
|
else if (stack->state == GUC_SAVE)
|
|
|
|
restorePrior = true;
|
|
|
|
else if (stack->nest_level == 1)
|
|
|
|
{
|
|
|
|
/* transaction commit */
|
|
|
|
if (stack->state == GUC_SET_LOCAL)
|
|
|
|
restoreMasked = true;
|
|
|
|
else if (stack->state == GUC_SET)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
/* we keep the current active value */
|
|
|
|
discard_stack_value(gconf, &stack->prior);
|
|
|
|
}
|
2007-11-15 22:14:46 +01:00
|
|
|
else /* must be GUC_LOCAL */
|
2007-09-11 02:06:42 +02:00
|
|
|
restorePrior = true;
|
|
|
|
}
|
|
|
|
else if (prev == NULL ||
|
|
|
|
prev->nest_level < stack->nest_level - 1)
|
|
|
|
{
|
|
|
|
/* decrement entry's level and do not pop it */
|
|
|
|
stack->nest_level--;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
2007-11-15 22:14:46 +01:00
|
|
|
* We have to merge this stack entry into prev. See README for
|
|
|
|
* discussion of this bit.
|
2007-09-11 02:06:42 +02:00
|
|
|
*/
|
|
|
|
switch (stack->state)
|
|
|
|
{
|
|
|
|
case GUC_SAVE:
|
2007-11-15 22:14:46 +01:00
|
|
|
Assert(false); /* can't get here */
|
2007-09-11 02:06:42 +02:00
|
|
|
|
|
|
|
case GUC_SET:
|
|
|
|
/* next level always becomes SET */
|
|
|
|
discard_stack_value(gconf, &stack->prior);
|
|
|
|
if (prev->state == GUC_SET_LOCAL)
|
|
|
|
discard_stack_value(gconf, &prev->masked);
|
|
|
|
prev->state = GUC_SET;
|
|
|
|
break;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
case GUC_LOCAL:
|
|
|
|
if (prev->state == GUC_SET)
|
|
|
|
{
|
|
|
|
/* LOCAL migrates down */
|
|
|
|
prev->masked = stack->prior;
|
|
|
|
prev->state = GUC_SET_LOCAL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* else just forget this stack level */
|
|
|
|
discard_stack_value(gconf, &stack->prior);
|
|
|
|
}
|
|
|
|
break;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
case GUC_SET_LOCAL:
|
|
|
|
/* prior state at this level no longer wanted */
|
|
|
|
discard_stack_value(gconf, &stack->prior);
|
|
|
|
/* copy down the masked state */
|
|
|
|
if (prev->state == GUC_SET_LOCAL)
|
|
|
|
discard_stack_value(gconf, &prev->masked);
|
|
|
|
prev->masked = stack->masked;
|
|
|
|
prev->state = GUC_SET_LOCAL;
|
|
|
|
break;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2007-09-11 02:06:42 +02:00
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
changed = false;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
if (restorePrior || restoreMasked)
|
|
|
|
{
|
|
|
|
/* Perform appropriate restoration of the stacked value */
|
|
|
|
union config_var_value newvalue;
|
|
|
|
GucSource newsource;
|
|
|
|
|
|
|
|
if (restoreMasked)
|
|
|
|
{
|
|
|
|
newvalue = stack->masked;
|
|
|
|
newsource = PGC_S_SESSION;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2007-09-11 02:06:42 +02:00
|
|
|
else
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
newvalue = stack->prior;
|
|
|
|
newsource = stack->source;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
switch (gconf->vartype)
|
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
|
|
|
{
|
2007-11-15 22:14:46 +01:00
|
|
|
struct config_bool *conf = (struct config_bool *) gconf;
|
|
|
|
bool newval = newvalue.boolval;
|
|
|
|
|
|
|
|
if (*conf->variable != newval)
|
|
|
|
{
|
|
|
|
if (conf->assign_hook)
|
|
|
|
if (!(*conf->assign_hook) (newval,
|
|
|
|
true, PGC_S_OVERRIDE))
|
|
|
|
elog(LOG, "failed to commit %s",
|
|
|
|
conf->gen.name);
|
|
|
|
*conf->variable = newval;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
break;
|
2007-09-11 02:06:42 +02:00
|
|
|
}
|
|
|
|
case PGC_INT:
|
|
|
|
{
|
2007-11-15 22:14:46 +01:00
|
|
|
struct config_int *conf = (struct config_int *) gconf;
|
|
|
|
int newval = newvalue.intval;
|
|
|
|
|
|
|
|
if (*conf->variable != newval)
|
|
|
|
{
|
|
|
|
if (conf->assign_hook)
|
|
|
|
if (!(*conf->assign_hook) (newval,
|
|
|
|
true, PGC_S_OVERRIDE))
|
|
|
|
elog(LOG, "failed to commit %s",
|
|
|
|
conf->gen.name);
|
|
|
|
*conf->variable = newval;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
break;
|
2007-09-11 02:06:42 +02:00
|
|
|
}
|
|
|
|
case PGC_REAL:
|
|
|
|
{
|
2007-11-15 22:14:46 +01:00
|
|
|
struct config_real *conf = (struct config_real *) gconf;
|
|
|
|
double newval = newvalue.realval;
|
|
|
|
|
|
|
|
if (*conf->variable != newval)
|
|
|
|
{
|
|
|
|
if (conf->assign_hook)
|
|
|
|
if (!(*conf->assign_hook) (newval,
|
|
|
|
true, PGC_S_OVERRIDE))
|
|
|
|
elog(LOG, "failed to commit %s",
|
|
|
|
conf->gen.name);
|
|
|
|
*conf->variable = newval;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
break;
|
2007-09-11 02:06:42 +02:00
|
|
|
}
|
|
|
|
case PGC_STRING:
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2007-11-15 22:14:46 +01:00
|
|
|
struct config_string *conf = (struct config_string *) gconf;
|
|
|
|
char *newval = newvalue.stringval;
|
|
|
|
|
|
|
|
if (*conf->variable != newval)
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
2007-11-15 22:14:46 +01:00
|
|
|
if (conf->assign_hook && newval)
|
2007-09-11 02:06:42 +02:00
|
|
|
{
|
2007-11-15 22:14:46 +01:00
|
|
|
const char *newstr;
|
|
|
|
|
|
|
|
newstr = (*conf->assign_hook) (newval, true,
|
|
|
|
PGC_S_OVERRIDE);
|
|
|
|
if (newstr == NULL)
|
|
|
|
elog(LOG, "failed to commit %s",
|
|
|
|
conf->gen.name);
|
|
|
|
else if (newstr != newval)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* If newval should now be freed,
|
|
|
|
* it'll be taken care of below.
|
|
|
|
*
|
|
|
|
* See notes in set_config_option
|
|
|
|
* about casting
|
|
|
|
*/
|
|
|
|
newval = (char *) newstr;
|
|
|
|
}
|
2007-09-11 02:06:42 +02:00
|
|
|
}
|
2007-11-15 22:14:46 +01:00
|
|
|
|
|
|
|
set_string_field(conf, conf->variable, newval);
|
|
|
|
changed = true;
|
2002-09-04 22:31:48 +02:00
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
/*
|
|
|
|
* Release stacked values if not used anymore. We
|
|
|
|
* could use discard_stack_value() here, but since
|
|
|
|
* we have type-specific code anyway, might as
|
|
|
|
* well inline it.
|
|
|
|
*/
|
|
|
|
set_string_field(conf, &stack->prior.stringval, NULL);
|
|
|
|
set_string_field(conf, &stack->masked.stringval, NULL);
|
|
|
|
break;
|
2007-09-11 02:06:42 +02:00
|
|
|
}
|
2008-03-10 13:55:13 +01:00
|
|
|
case PGC_ENUM:
|
|
|
|
{
|
|
|
|
struct config_enum *conf = (struct config_enum *) gconf;
|
|
|
|
int newval = newvalue.enumval;
|
|
|
|
|
|
|
|
if (*conf->variable != newval)
|
|
|
|
{
|
|
|
|
if (conf->assign_hook)
|
|
|
|
if (!(*conf->assign_hook) (newval,
|
|
|
|
true, PGC_S_OVERRIDE))
|
|
|
|
elog(LOG, "failed to commit %s",
|
|
|
|
conf->gen.name);
|
|
|
|
*conf->variable = newval;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2003-04-25 21:45:10 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
gconf->source = newsource;
|
|
|
|
}
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
/* Finish popping the state stack */
|
|
|
|
gconf->stack = prev;
|
|
|
|
pfree(stack);
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
/* Report new value if we changed it */
|
|
|
|
if (changed && (gconf->flags & GUC_REPORT))
|
|
|
|
ReportGUCOption(gconf);
|
2007-11-15 22:14:46 +01:00
|
|
|
} /* end of stack-popping loop */
|
2007-09-11 02:06:42 +02:00
|
|
|
|
|
|
|
if (stack != NULL)
|
|
|
|
still_dirty = true;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
/* If there are no remaining stack entries, we can reset guc_dirty */
|
|
|
|
guc_dirty = still_dirty;
|
2007-09-03 02:39:26 +02:00
|
|
|
|
|
|
|
/* Update nesting level */
|
|
|
|
GUCNestLevel = nestLevel - 1;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-04-25 21:45:10 +02:00
|
|
|
/*
|
|
|
|
* Start up automatic reporting of changes to variables marked GUC_REPORT.
|
|
|
|
* This is executed at completion of backend startup.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
BeginReportingGUCOptions(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Don't do anything unless talking to an interactive frontend of protocol
|
|
|
|
* 3.0 or later.
|
2003-04-25 21:45:10 +02:00
|
|
|
*/
|
2005-11-03 18:11:40 +01:00
|
|
|
if (whereToSendOutput != DestRemote ||
|
2003-04-25 21:45:10 +02:00
|
|
|
PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
|
|
|
|
return;
|
|
|
|
|
|
|
|
reporting_enabled = true;
|
|
|
|
|
|
|
|
/* Transmit initial values of interesting variables */
|
|
|
|
for (i = 0; i < num_guc_variables; i++)
|
|
|
|
{
|
|
|
|
struct config_generic *conf = guc_variables[i];
|
|
|
|
|
|
|
|
if (conf->flags & GUC_REPORT)
|
|
|
|
ReportGUCOption(conf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ReportGUCOption: if appropriate, transmit option value to frontend
|
|
|
|
*/
|
|
|
|
static void
|
2003-07-04 18:41:22 +02:00
|
|
|
ReportGUCOption(struct config_generic * record)
|
2003-04-25 21:45:10 +02:00
|
|
|
{
|
|
|
|
if (reporting_enabled && (record->flags & GUC_REPORT))
|
|
|
|
{
|
2006-07-27 10:30:41 +02:00
|
|
|
char *val = _ShowOption(record, false);
|
2003-04-25 21:45:10 +02:00
|
|
|
StringInfoData msgbuf;
|
|
|
|
|
|
|
|
pq_beginmessage(&msgbuf, 'S');
|
|
|
|
pq_sendstring(&msgbuf, record->name);
|
|
|
|
pq_sendstring(&msgbuf, val);
|
|
|
|
pq_endmessage(&msgbuf);
|
|
|
|
|
|
|
|
pfree(val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
|
|
|
* Try to interpret value as boolean value. Valid values are: true,
|
2007-06-22 00:59:12 +02:00
|
|
|
* false, yes, no, on, off, 1, 0; as well as unique prefixes thereof.
|
|
|
|
* If the string parses okay, return true, else false.
|
|
|
|
* If okay and result is not NULL, return the value in *result.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
parse_bool(const char *value, bool *result)
|
|
|
|
{
|
|
|
|
size_t len = strlen(value);
|
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
if (pg_strncasecmp(value, "true", len) == 0)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
|
|
|
if (result)
|
|
|
|
*result = true;
|
|
|
|
}
|
2004-05-07 02:24:59 +02:00
|
|
|
else if (pg_strncasecmp(value, "false", len) == 0)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
|
|
|
if (result)
|
|
|
|
*result = false;
|
|
|
|
}
|
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
else if (pg_strncasecmp(value, "yes", len) == 0)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
|
|
|
if (result)
|
|
|
|
*result = true;
|
|
|
|
}
|
2004-05-07 02:24:59 +02:00
|
|
|
else if (pg_strncasecmp(value, "no", len) == 0)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
|
|
|
if (result)
|
|
|
|
*result = false;
|
|
|
|
}
|
|
|
|
|
2006-12-23 01:52:40 +01:00
|
|
|
/* 'o' is not unique enough */
|
|
|
|
else if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
|
|
|
if (result)
|
|
|
|
*result = true;
|
|
|
|
}
|
2006-12-23 01:52:40 +01:00
|
|
|
else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
|
|
|
if (result)
|
|
|
|
*result = false;
|
|
|
|
}
|
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
else if (pg_strcasecmp(value, "1") == 0)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
|
|
|
if (result)
|
|
|
|
*result = true;
|
|
|
|
}
|
2004-05-07 02:24:59 +02:00
|
|
|
else if (pg_strcasecmp(value, "0") == 0)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
|
|
|
if (result)
|
|
|
|
*result = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
2005-09-25 00:54:44 +02:00
|
|
|
{
|
|
|
|
if (result)
|
|
|
|
*result = false; /* suppress compiler warning */
|
2002-05-17 03:19:19 +02:00
|
|
|
return false;
|
2005-09-25 00:54:44 +02:00
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Try to parse value as an integer. The accepted formats are the
|
2007-06-21 20:14:21 +02:00
|
|
|
* usual decimal, octal, or hexadecimal formats, optionally followed by
|
|
|
|
* a unit name if "flags" indicates a unit is allowed.
|
|
|
|
*
|
|
|
|
* If the string parses okay, return true, else false.
|
|
|
|
* If okay and result is not NULL, return the value in *result.
|
|
|
|
* If not okay and hintmsg is not NULL, *hintmsg is set to a suitable
|
|
|
|
* HINT message, or NULL if no hint provided.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
|
|
|
static bool
|
2007-06-21 20:14:21 +02:00
|
|
|
parse_int(const char *value, int *result, int flags, const char **hintmsg)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2007-06-21 20:14:21 +02:00
|
|
|
int64 val;
|
2002-05-17 03:19:19 +02:00
|
|
|
char *endptr;
|
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
/* To suppress compiler warnings, always set output params */
|
|
|
|
if (result)
|
|
|
|
*result = 0;
|
|
|
|
if (hintmsg)
|
|
|
|
*hintmsg = NULL;
|
|
|
|
|
|
|
|
/* We assume here that int64 is at least as wide as long */
|
2002-05-17 03:19:19 +02:00
|
|
|
errno = 0;
|
|
|
|
val = strtol(value, &endptr, 0);
|
2006-07-27 10:30:41 +02:00
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
if (endptr == value)
|
|
|
|
return false; /* no HINT for integer syntax error */
|
|
|
|
|
|
|
|
if (errno == ERANGE || val != (int64) ((int32) val))
|
2006-07-27 10:30:41 +02:00
|
|
|
{
|
2007-06-21 20:14:21 +02:00
|
|
|
if (hintmsg)
|
|
|
|
*hintmsg = gettext_noop("Value exceeds integer range.");
|
|
|
|
return false;
|
|
|
|
}
|
2006-07-27 10:30:41 +02:00
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
/* allow whitespace between integer and unit */
|
|
|
|
while (isspace((unsigned char) *endptr))
|
|
|
|
endptr++;
|
2006-07-27 10:30:41 +02:00
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
/* Handle possible unit */
|
|
|
|
if (*endptr != '\0')
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Note: the multiple-switch coding technique here is a bit tedious,
|
|
|
|
* but seems necessary to avoid intermediate-value overflows.
|
|
|
|
*
|
|
|
|
* If INT64_IS_BUSTED (ie, it's really int32) we will fail to detect
|
|
|
|
* overflow due to units conversion, but there are few enough such
|
|
|
|
* machines that it does not seem worth trying to be smarter.
|
|
|
|
*/
|
|
|
|
if (flags & GUC_UNIT_MEMORY)
|
2006-07-27 10:30:41 +02:00
|
|
|
{
|
2007-06-21 20:14:21 +02:00
|
|
|
/* Set hint for use if no match or trailing garbage */
|
|
|
|
if (hintmsg)
|
|
|
|
*hintmsg = gettext_noop("Valid units for this parameter are \"kB\", \"MB\", and \"GB\".");
|
2006-07-27 10:30:41 +02:00
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
#if BLCKSZ < 1024 || BLCKSZ > (1024*1024)
|
|
|
|
#error BLCKSZ must be between 1KB and 1MB
|
|
|
|
#endif
|
|
|
|
#if XLOG_BLCKSZ < 1024 || XLOG_BLCKSZ > (1024*1024)
|
|
|
|
#error XLOG_BLCKSZ must be between 1KB and 1MB
|
2007-02-23 22:36:19 +01:00
|
|
|
#endif
|
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
if (strncmp(endptr, "kB", 2) == 0)
|
2006-10-03 23:11:55 +02:00
|
|
|
{
|
2007-06-21 20:14:21 +02:00
|
|
|
endptr += 2;
|
|
|
|
switch (flags & GUC_UNIT_MEMORY)
|
|
|
|
{
|
|
|
|
case GUC_UNIT_BLOCKS:
|
|
|
|
val /= (BLCKSZ / 1024);
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_XBLOCKS:
|
|
|
|
val /= (XLOG_BLCKSZ / 1024);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strncmp(endptr, "MB", 2) == 0)
|
|
|
|
{
|
|
|
|
endptr += 2;
|
|
|
|
switch (flags & GUC_UNIT_MEMORY)
|
|
|
|
{
|
|
|
|
case GUC_UNIT_KB:
|
|
|
|
val *= KB_PER_MB;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_BLOCKS:
|
|
|
|
val *= KB_PER_MB / (BLCKSZ / 1024);
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_XBLOCKS:
|
|
|
|
val *= KB_PER_MB / (XLOG_BLCKSZ / 1024);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strncmp(endptr, "GB", 2) == 0)
|
|
|
|
{
|
|
|
|
endptr += 2;
|
|
|
|
switch (flags & GUC_UNIT_MEMORY)
|
|
|
|
{
|
|
|
|
case GUC_UNIT_KB:
|
|
|
|
val *= KB_PER_GB;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_BLOCKS:
|
|
|
|
val *= KB_PER_GB / (BLCKSZ / 1024);
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_XBLOCKS:
|
|
|
|
val *= KB_PER_GB / (XLOG_BLCKSZ / 1024);
|
|
|
|
break;
|
|
|
|
}
|
2006-10-03 23:11:55 +02:00
|
|
|
}
|
|
|
|
}
|
2007-06-21 20:14:21 +02:00
|
|
|
else if (flags & GUC_UNIT_TIME)
|
|
|
|
{
|
|
|
|
/* Set hint for use if no match or trailing garbage */
|
|
|
|
if (hintmsg)
|
|
|
|
*hintmsg = gettext_noop("Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\".");
|
2006-07-27 10:30:41 +02:00
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
if (strncmp(endptr, "ms", 2) == 0)
|
|
|
|
{
|
|
|
|
endptr += 2;
|
|
|
|
switch (flags & GUC_UNIT_TIME)
|
|
|
|
{
|
|
|
|
case GUC_UNIT_S:
|
|
|
|
val /= MS_PER_S;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_MIN:
|
|
|
|
val /= MS_PER_MIN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strncmp(endptr, "s", 1) == 0)
|
|
|
|
{
|
|
|
|
endptr += 1;
|
|
|
|
switch (flags & GUC_UNIT_TIME)
|
|
|
|
{
|
|
|
|
case GUC_UNIT_MS:
|
|
|
|
val *= MS_PER_S;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_MIN:
|
|
|
|
val /= S_PER_MIN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strncmp(endptr, "min", 3) == 0)
|
|
|
|
{
|
|
|
|
endptr += 3;
|
|
|
|
switch (flags & GUC_UNIT_TIME)
|
|
|
|
{
|
|
|
|
case GUC_UNIT_MS:
|
|
|
|
val *= MS_PER_MIN;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_S:
|
|
|
|
val *= S_PER_MIN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strncmp(endptr, "h", 1) == 0)
|
|
|
|
{
|
|
|
|
endptr += 1;
|
|
|
|
switch (flags & GUC_UNIT_TIME)
|
|
|
|
{
|
|
|
|
case GUC_UNIT_MS:
|
|
|
|
val *= MS_PER_H;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_S:
|
|
|
|
val *= S_PER_H;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_MIN:
|
|
|
|
val *= MIN_PER_H;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strncmp(endptr, "d", 1) == 0)
|
|
|
|
{
|
|
|
|
endptr += 1;
|
|
|
|
switch (flags & GUC_UNIT_TIME)
|
|
|
|
{
|
|
|
|
case GUC_UNIT_MS:
|
|
|
|
val *= MS_PER_D;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_S:
|
|
|
|
val *= S_PER_D;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_MIN:
|
|
|
|
val *= MIN_PER_D;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-07-27 10:30:41 +02:00
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
/* allow whitespace after unit */
|
|
|
|
while (isspace((unsigned char) *endptr))
|
2006-07-27 10:30:41 +02:00
|
|
|
endptr++;
|
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
if (*endptr != '\0')
|
|
|
|
return false; /* appropriate hint, if any, already set */
|
2006-07-27 10:30:41 +02:00
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
/* Check for overflow due to units conversion */
|
|
|
|
if (val != (int64) ((int32) val))
|
2006-10-03 23:11:55 +02:00
|
|
|
{
|
2007-06-21 20:14:21 +02:00
|
|
|
if (hintmsg)
|
|
|
|
*hintmsg = gettext_noop("Value exceeds integer range.");
|
|
|
|
return false;
|
2006-10-03 23:11:55 +02:00
|
|
|
}
|
2006-07-27 10:30:41 +02:00
|
|
|
}
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
if (result)
|
|
|
|
*result = (int) val;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2007-06-22 00:59:12 +02:00
|
|
|
* Try to parse value as a floating point number in the usual format.
|
|
|
|
* If the string parses okay, return true, else false.
|
|
|
|
* If okay and result is not NULL, return the value in *result.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
parse_real(const char *value, double *result)
|
|
|
|
{
|
|
|
|
double val;
|
|
|
|
char *endptr;
|
|
|
|
|
2007-06-22 00:59:12 +02:00
|
|
|
if (result)
|
|
|
|
*result = 0; /* suppress compiler warning */
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
errno = 0;
|
|
|
|
val = strtod(value, &endptr);
|
2007-06-22 00:59:12 +02:00
|
|
|
if (endptr == value || errno == ERANGE)
|
2002-05-17 03:19:19 +02:00
|
|
|
return false;
|
2007-06-22 00:59:12 +02:00
|
|
|
|
|
|
|
/* allow whitespace after number */
|
|
|
|
while (isspace((unsigned char) *endptr))
|
|
|
|
endptr++;
|
|
|
|
if (*endptr != '\0')
|
|
|
|
return false;
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
if (result)
|
|
|
|
*result = val;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-10 13:55:13 +01:00
|
|
|
/*
|
|
|
|
* Lookup the name for an enum option with the selected value.
|
|
|
|
* Should only ever be called with known-valid values, so throws
|
|
|
|
* an elog(ERROR) if the enum option is not found.
|
|
|
|
*
|
|
|
|
* The returned string is a pointer to static data and not
|
|
|
|
* allocated for modification.
|
|
|
|
*/
|
|
|
|
static const char *
|
|
|
|
config_enum_lookup_value(struct config_enum *record, int val)
|
|
|
|
{
|
|
|
|
const struct config_enum_entry *entry = record->options;
|
|
|
|
while (entry && entry->name)
|
|
|
|
{
|
|
|
|
if (entry->val == val)
|
|
|
|
return entry->name;
|
|
|
|
entry++;
|
|
|
|
}
|
|
|
|
elog(ERROR, "could not find enum option %d for %s",
|
|
|
|
val, record->gen.name);
|
|
|
|
return NULL; /* silence compiler */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Lookup the value for an enum option with the selected name
|
|
|
|
* (case-insensitive).
|
|
|
|
* If the enum option is found, sets the retval value and returns
|
|
|
|
* true. If it's not found, return FALSE and don't touch retval.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
config_enum_lookup_name(struct config_enum *record, const char *value, int *retval)
|
|
|
|
{
|
|
|
|
const struct config_enum_entry *entry = record->options;
|
|
|
|
|
|
|
|
if (retval)
|
|
|
|
*retval = 0; /* suppress compiler warning */
|
|
|
|
|
|
|
|
while (entry && entry->name)
|
|
|
|
{
|
|
|
|
if (!pg_strcasecmp(value, entry->name))
|
|
|
|
{
|
|
|
|
*retval = entry->val;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
entry++;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Returna list of all available options for an enum, separated
|
|
|
|
* by ", " (comma-space).
|
|
|
|
* If prefix is gievn, it is added before the first enum value.
|
|
|
|
* If suffix is given, it is added to the end of the string.
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
config_enum_get_options(struct config_enum *record, const char *prefix, const char *suffix)
|
|
|
|
{
|
|
|
|
const struct config_enum_entry *entry = record->options;
|
|
|
|
int len = 0;
|
|
|
|
char *hintmsg;
|
|
|
|
|
|
|
|
if (!entry || !entry->name)
|
|
|
|
return NULL; /* Should not happen */
|
|
|
|
|
|
|
|
while (entry && entry->name)
|
|
|
|
{
|
|
|
|
len += strlen(entry->name) + 2; /* string and ", " */
|
|
|
|
entry++;
|
|
|
|
}
|
|
|
|
|
|
|
|
hintmsg = palloc(len + strlen(prefix) + strlen(suffix) + 2);
|
|
|
|
|
|
|
|
strcpy(hintmsg, prefix);
|
|
|
|
|
|
|
|
entry = record->options;
|
|
|
|
while (entry && entry->name)
|
|
|
|
{
|
|
|
|
strcat(hintmsg, entry->name);
|
|
|
|
strcat(hintmsg, ", ");
|
|
|
|
entry++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Replace final comma/space */
|
|
|
|
hintmsg[strlen(hintmsg)-2] = '\0';
|
|
|
|
strcat(hintmsg, suffix);
|
|
|
|
|
|
|
|
return hintmsg;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-26 00:12:34 +02:00
|
|
|
/*
|
|
|
|
* Call a GucStringAssignHook function, being careful to free the
|
|
|
|
* "newval" string if the hook ereports.
|
|
|
|
*
|
|
|
|
* This is split out of set_config_option just to avoid the "volatile"
|
|
|
|
* qualifiers that would otherwise have to be plastered all over.
|
|
|
|
*/
|
|
|
|
static const char *
|
|
|
|
call_string_assign_hook(GucStringAssignHook assign_hook,
|
|
|
|
char *newval, bool doit, GucSource source)
|
|
|
|
{
|
|
|
|
const char *result;
|
|
|
|
|
|
|
|
PG_TRY();
|
|
|
|
{
|
|
|
|
result = (*assign_hook) (newval, doit, source);
|
|
|
|
}
|
|
|
|
PG_CATCH();
|
|
|
|
{
|
|
|
|
free(newval);
|
|
|
|
PG_RE_THROW();
|
|
|
|
}
|
|
|
|
PG_END_TRY();
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
2006-08-14 04:27:27 +02:00
|
|
|
* Sets option `name' to given value. The value should be a string
|
|
|
|
* which is going to be parsed and converted to the appropriate data
|
|
|
|
* type. The context and source parameters indicate in which context this
|
|
|
|
* function is being called so it can apply the access restrictions
|
|
|
|
* properly.
|
|
|
|
*
|
2007-09-11 02:06:42 +02:00
|
|
|
* If value is NULL, set the option to its default value (normally the
|
|
|
|
* reset_val, but if source == PGC_S_DEFAULT we instead use the boot_val).
|
|
|
|
*
|
|
|
|
* action indicates whether to set the value globally in the session, locally
|
|
|
|
* to the current top transaction, or just for the duration of a function call.
|
|
|
|
*
|
|
|
|
* If changeVal is false then don't really set the option but do all
|
2006-08-14 04:27:27 +02:00
|
|
|
* the checks to see if it would work.
|
|
|
|
*
|
|
|
|
* If there is an error (non-existing option, invalid value) then an
|
|
|
|
* ereport(ERROR) is thrown *unless* this is called in a context where we
|
|
|
|
* don't want to ereport (currently, startup or SIGHUP config file reread).
|
2007-12-28 01:23:23 +01:00
|
|
|
* In that case we write a suitable error message via ereport(LOG) and
|
2006-08-14 04:27:27 +02:00
|
|
|
* return false. This is working around the deficiencies in the ereport
|
|
|
|
* mechanism, so don't blame me. In all other cases, the function
|
|
|
|
* returns true, including cases where the input is valid but we chose
|
|
|
|
* not to apply it because of context or source-priority considerations.
|
|
|
|
*
|
|
|
|
* See also SetConfigOption for an external interface.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
2006-08-14 04:27:27 +02:00
|
|
|
bool
|
|
|
|
set_config_option(const char *name, const char *value,
|
|
|
|
GucContext context, GucSource source,
|
2007-09-11 02:06:42 +02:00
|
|
|
GucAction action, bool changeVal)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2006-08-14 04:27:27 +02:00
|
|
|
struct config_generic *record;
|
|
|
|
int elevel;
|
|
|
|
bool makeDefault;
|
2006-08-13 03:30:17 +02:00
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
if (context == PGC_SIGHUP || source == PGC_S_DEFAULT)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* To avoid cluttering the log, only the postmaster bleats loudly
|
|
|
|
* about problems with the config file.
|
|
|
|
*/
|
2007-12-28 01:23:23 +01:00
|
|
|
elevel = IsUnderPostmaster ? DEBUG3 : LOG;
|
2006-08-14 04:27:27 +02:00
|
|
|
}
|
|
|
|
else if (source == PGC_S_DATABASE || source == PGC_S_USER)
|
|
|
|
elevel = INFO;
|
|
|
|
else
|
|
|
|
elevel = ERROR;
|
2006-08-13 03:30:17 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
record = find_option(name, true, elevel);
|
2006-08-14 04:27:27 +02:00
|
|
|
if (record == NULL)
|
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("unrecognized configuration parameter \"%s\"", name)));
|
|
|
|
return false;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
|
2007-04-21 22:02:41 +02:00
|
|
|
/*
|
2007-11-15 22:14:46 +01:00
|
|
|
* If source is postgresql.conf, mark the found record with
|
|
|
|
* GUC_IS_IN_FILE. This is for the convenience of ProcessConfigFile. Note
|
|
|
|
* that we do it even if changeVal is false, since ProcessConfigFile wants
|
|
|
|
* the marking to occur during its testing pass.
|
2007-04-21 22:02:41 +02:00
|
|
|
*/
|
2007-09-10 02:57:22 +02:00
|
|
|
if (source == PGC_S_FILE)
|
|
|
|
record->status |= GUC_IS_IN_FILE;
|
2007-04-21 22:02:41 +02:00
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
/*
|
|
|
|
* 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 and return true.
|
|
|
|
*/
|
2002-05-17 03:19:19 +02:00
|
|
|
switch (record->context)
|
|
|
|
{
|
2003-04-25 21:45:10 +02:00
|
|
|
case PGC_INTERNAL:
|
2006-08-14 04:27:27 +02:00
|
|
|
if (context == PGC_SIGHUP)
|
|
|
|
return true;
|
2003-04-25 21:45:10 +02:00
|
|
|
if (context != PGC_INTERNAL)
|
|
|
|
{
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
|
2003-09-25 08:58:07 +02:00
|
|
|
errmsg("parameter \"%s\" cannot be changed",
|
2006-08-14 04:27:27 +02:00
|
|
|
name)));
|
2003-04-25 21:45:10 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
2002-05-17 03:19:19 +02:00
|
|
|
case PGC_POSTMASTER:
|
|
|
|
if (context == PGC_SIGHUP)
|
2006-08-14 04:27:27 +02:00
|
|
|
{
|
2007-09-10 02:57:22 +02:00
|
|
|
/*
|
|
|
|
* We are reading a PGC_POSTMASTER var from postgresql.conf.
|
|
|
|
* We can't change the setting, so give a warning if the DBA
|
2007-11-15 22:14:46 +01:00
|
|
|
* tries to change it. (Throwing an error would be more
|
2007-09-10 02:57:22 +02:00
|
|
|
* consistent, but seems overly rigid.)
|
|
|
|
*/
|
2006-08-14 04:27:27 +02:00
|
|
|
if (changeVal && !is_newvalue_equal(record, value))
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
|
|
|
|
errmsg("parameter \"%s\" cannot be changed after server start; configuration file change ignored",
|
|
|
|
name)));
|
|
|
|
return true;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
if (context != PGC_POSTMASTER)
|
|
|
|
{
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
|
2004-08-29 07:07:03 +02:00
|
|
|
errmsg("parameter \"%s\" cannot be changed after server start",
|
2006-08-14 04:27:27 +02:00
|
|
|
name)));
|
2002-05-17 03:19:19 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PGC_SIGHUP:
|
|
|
|
if (context != PGC_SIGHUP && context != PGC_POSTMASTER)
|
|
|
|
{
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
|
2003-09-25 08:58:07 +02:00
|
|
|
errmsg("parameter \"%s\" cannot be changed now",
|
2006-08-14 04:27:27 +02:00
|
|
|
name)));
|
2002-05-17 03:19:19 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Hmm, the idea of the SIGHUP context is "ought to be global, but
|
|
|
|
* can be changed after postmaster start". But there's nothing
|
|
|
|
* that prevents a crafty administrator from sending SIGHUP
|
|
|
|
* signals to individual backends only.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
|
|
|
break;
|
|
|
|
case PGC_BACKEND:
|
|
|
|
if (context == PGC_SIGHUP)
|
|
|
|
{
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* If a PGC_BACKEND parameter is changed in the config file,
|
|
|
|
* we want to accept the new value in the postmaster (whence
|
|
|
|
* it will propagate to subsequently-started backends), but
|
|
|
|
* ignore it in existing backends. This is a tad klugy, but
|
|
|
|
* necessary because we don't re-read the config file during
|
|
|
|
* backend start.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
|
|
|
if (IsUnderPostmaster)
|
2006-08-14 04:27:27 +02:00
|
|
|
return true;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
else if (context != PGC_BACKEND && context != PGC_POSTMASTER)
|
|
|
|
{
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
|
2004-08-29 07:07:03 +02:00
|
|
|
errmsg("parameter \"%s\" cannot be set after connection start",
|
2006-08-14 04:27:27 +02:00
|
|
|
name)));
|
2002-05-17 03:19:19 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PGC_SUSET:
|
|
|
|
if (context == PGC_USERSET || context == PGC_BACKEND)
|
|
|
|
{
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
2005-10-15 04:49:52 +02:00
|
|
|
errmsg("permission denied to set parameter \"%s\"",
|
2006-08-14 04:27:27 +02:00
|
|
|
name)));
|
2002-05-17 03:19:19 +02:00
|
|
|
return false;
|
2001-09-30 22:16:21 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PGC_USERSET:
|
|
|
|
/* always okay */
|
|
|
|
break;
|
2000-06-23 00:31:24 +02:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 22:32:29 +02:00
|
|
|
/*
|
2007-11-15 22:14:46 +01:00
|
|
|
* Should we set reset/stacked values? (If so, the behavior is not
|
|
|
|
* transactional.) This is done either when we get a default value from
|
|
|
|
* the database's/user's/client's default settings or when we reset a
|
|
|
|
* value to its default.
|
2002-05-17 22:32:29 +02:00
|
|
|
*/
|
2007-09-10 02:57:22 +02:00
|
|
|
makeDefault = changeVal && (source <= PGC_S_OVERRIDE) &&
|
|
|
|
((value != NULL) || source == PGC_S_DEFAULT);
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
/*
|
2007-09-10 02:57:22 +02:00
|
|
|
* Ignore attempted set if overridden by previously processed setting.
|
|
|
|
* However, if changeVal is false then plow ahead anyway since we are
|
|
|
|
* trying to find out if the value is potentially good, not actually use
|
|
|
|
* it. Also keep going if makeDefault is true, since we may want to set
|
|
|
|
* the reset/stacked values even if we can't set the variable itself.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
2007-09-10 02:57:22 +02:00
|
|
|
if (record->source > source)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2003-09-01 06:15:51 +02:00
|
|
|
if (changeVal && !makeDefault)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(DEBUG3, "\"%s\": setting ignored because previous source is higher priority",
|
2002-05-17 03:19:19 +02:00
|
|
|
name);
|
|
|
|
return true;
|
|
|
|
}
|
2004-11-14 20:35:35 +01:00
|
|
|
changeVal = false;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
|
2000-06-23 00:31:24 +02:00
|
|
|
/*
|
2004-11-14 20:35:35 +01:00
|
|
|
* Evaluate value and set variable.
|
2000-06-23 00:31:24 +02:00
|
|
|
*/
|
2002-05-17 03:19:19 +02:00
|
|
|
switch (record->vartype)
|
2001-01-24 19:37:31 +01:00
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
struct config_bool *conf = (struct config_bool *) record;
|
2002-05-17 03:19:19 +02:00
|
|
|
bool newval;
|
2006-08-14 04:27:27 +02:00
|
|
|
|
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
if (!parse_bool(value, &newval))
|
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("parameter \"%s\" requires a Boolean value",
|
|
|
|
name)));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2007-04-21 22:02:41 +02:00
|
|
|
else if (source == PGC_S_DEFAULT)
|
|
|
|
newval = conf->boot_val;
|
2006-08-14 04:27:27 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
newval = conf->reset_val;
|
|
|
|
source = conf->gen.reset_source;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (conf->assign_hook)
|
|
|
|
if (!(*conf->assign_hook) (newval, changeVal, source))
|
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("invalid value for parameter \"%s\": %d",
|
|
|
|
name, (int) newval)));
|
|
|
|
return false;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2003-09-01 06:15:51 +02:00
|
|
|
if (changeVal || makeDefault)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2004-07-01 02:52:04 +02:00
|
|
|
/* Save old value to support transaction abort */
|
|
|
|
if (!makeDefault)
|
2007-09-11 02:06:42 +02:00
|
|
|
push_old_value(&conf->gen, action);
|
2003-09-01 06:15:51 +02:00
|
|
|
if (changeVal)
|
2001-06-07 06:50:57 +02:00
|
|
|
{
|
2002-05-17 03:19:19 +02:00
|
|
|
*conf->variable = newval;
|
|
|
|
conf->gen.source = source;
|
|
|
|
}
|
|
|
|
if (makeDefault)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
GucStack *stack;
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
if (conf->gen.reset_source <= source)
|
|
|
|
{
|
|
|
|
conf->reset_val = newval;
|
|
|
|
conf->gen.reset_source = source;
|
|
|
|
}
|
2004-07-01 02:52:04 +02:00
|
|
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2004-07-01 02:52:04 +02:00
|
|
|
if (stack->source <= source)
|
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
stack->prior.boolval = newval;
|
2004-07-01 02:52:04 +02:00
|
|
|
stack->source = source;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
}
|
2001-06-13 00:54:06 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
2001-01-24 19:37:31 +01:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
|
|
|
case PGC_INT:
|
2001-01-24 19:37:31 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
struct config_int *conf = (struct config_int *) record;
|
2002-05-17 03:19:19 +02:00
|
|
|
int newval;
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
if (value)
|
|
|
|
{
|
2007-06-21 20:14:21 +02:00
|
|
|
const char *hintmsg;
|
|
|
|
|
|
|
|
if (!parse_int(value, &newval, conf->gen.flags, &hintmsg))
|
2006-08-14 04:27:27 +02:00
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2007-11-15 22:14:46 +01:00
|
|
|
errmsg("invalid value for parameter \"%s\": \"%s\"",
|
|
|
|
name, value),
|
2007-06-21 20:14:21 +02:00
|
|
|
hintmsg ? errhint(hintmsg) : 0));
|
2006-08-14 04:27:27 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (newval < conf->min || newval > conf->max)
|
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
|
|
|
|
newval, name, conf->min, conf->max)));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2007-04-21 22:02:41 +02:00
|
|
|
else if (source == PGC_S_DEFAULT)
|
|
|
|
newval = conf->boot_val;
|
2006-08-14 04:27:27 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
newval = conf->reset_val;
|
|
|
|
source = conf->gen.reset_source;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (conf->assign_hook)
|
|
|
|
if (!(*conf->assign_hook) (newval, changeVal, source))
|
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("invalid value for parameter \"%s\": %d",
|
|
|
|
name, newval)));
|
|
|
|
return false;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2003-09-01 06:15:51 +02:00
|
|
|
if (changeVal || makeDefault)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2004-07-01 02:52:04 +02:00
|
|
|
/* Save old value to support transaction abort */
|
|
|
|
if (!makeDefault)
|
2007-09-11 02:06:42 +02:00
|
|
|
push_old_value(&conf->gen, action);
|
2003-09-01 06:15:51 +02:00
|
|
|
if (changeVal)
|
2001-06-07 06:50:57 +02:00
|
|
|
{
|
2002-05-17 03:19:19 +02:00
|
|
|
*conf->variable = newval;
|
|
|
|
conf->gen.source = source;
|
|
|
|
}
|
|
|
|
if (makeDefault)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
GucStack *stack;
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
if (conf->gen.reset_source <= source)
|
|
|
|
{
|
|
|
|
conf->reset_val = newval;
|
|
|
|
conf->gen.reset_source = source;
|
|
|
|
}
|
2004-07-01 02:52:04 +02:00
|
|
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2004-07-01 02:52:04 +02:00
|
|
|
if (stack->source <= source)
|
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
stack->prior.intval = newval;
|
2004-07-01 02:52:04 +02:00
|
|
|
stack->source = source;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
}
|
2001-06-13 00:54:06 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
2001-01-24 19:37:31 +01:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
|
|
|
case PGC_REAL:
|
2001-01-24 19:37:31 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
struct config_real *conf = (struct config_real *) record;
|
2002-05-17 03:19:19 +02:00
|
|
|
double newval;
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
if (!parse_real(value, &newval))
|
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("parameter \"%s\" requires a numeric value",
|
|
|
|
name)));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (newval < conf->min || newval > conf->max)
|
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("%g is outside the valid range for parameter \"%s\" (%g .. %g)",
|
|
|
|
newval, name, conf->min, conf->max)));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2007-04-21 22:02:41 +02:00
|
|
|
else if (source == PGC_S_DEFAULT)
|
|
|
|
newval = conf->boot_val;
|
2006-08-14 04:27:27 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
newval = conf->reset_val;
|
|
|
|
source = conf->gen.reset_source;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (conf->assign_hook)
|
|
|
|
if (!(*conf->assign_hook) (newval, changeVal, source))
|
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("invalid value for parameter \"%s\": %g",
|
|
|
|
name, newval)));
|
|
|
|
return false;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2003-09-01 06:15:51 +02:00
|
|
|
if (changeVal || makeDefault)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2004-07-01 02:52:04 +02:00
|
|
|
/* Save old value to support transaction abort */
|
|
|
|
if (!makeDefault)
|
2007-09-11 02:06:42 +02:00
|
|
|
push_old_value(&conf->gen, action);
|
2003-09-01 06:15:51 +02:00
|
|
|
if (changeVal)
|
2001-06-07 06:50:57 +02:00
|
|
|
{
|
2002-05-17 03:19:19 +02:00
|
|
|
*conf->variable = newval;
|
|
|
|
conf->gen.source = source;
|
|
|
|
}
|
|
|
|
if (makeDefault)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
GucStack *stack;
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
if (conf->gen.reset_source <= source)
|
|
|
|
{
|
|
|
|
conf->reset_val = newval;
|
|
|
|
conf->gen.reset_source = source;
|
|
|
|
}
|
2004-07-01 02:52:04 +02:00
|
|
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2004-07-01 02:52:04 +02:00
|
|
|
if (stack->source <= source)
|
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
stack->prior.realval = newval;
|
2004-07-01 02:52:04 +02:00
|
|
|
stack->source = source;
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
}
|
2001-06-13 00:54:06 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
2001-01-24 19:37:31 +01:00
|
|
|
}
|
2000-05-31 02:28:42 +02:00
|
|
|
|
|
|
|
case PGC_STRING:
|
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
struct config_string *conf = (struct config_string *) record;
|
2002-05-17 03:19:19 +02:00
|
|
|
char *newval;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
newval = guc_strdup(elevel, value);
|
|
|
|
if (newval == NULL)
|
|
|
|
return false;
|
2006-10-04 02:30:14 +02:00
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
/*
|
2006-10-04 02:30:14 +02:00
|
|
|
* The only sort of "parsing" check we need to do is apply
|
|
|
|
* truncation if GUC_IS_NAME.
|
2006-08-14 04:27:27 +02:00
|
|
|
*/
|
|
|
|
if (conf->gen.flags & GUC_IS_NAME)
|
|
|
|
truncate_identifier(newval, strlen(newval), true);
|
|
|
|
}
|
2007-04-21 22:02:41 +02:00
|
|
|
else if (source == PGC_S_DEFAULT)
|
|
|
|
{
|
|
|
|
if (conf->boot_val == NULL)
|
|
|
|
newval = NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
newval = guc_strdup(elevel, conf->boot_val);
|
|
|
|
if (newval == NULL)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2007-09-10 02:57:22 +02:00
|
|
|
else
|
2006-08-14 04:27:27 +02:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* We could possibly avoid strdup here, but easier to make
|
2007-09-10 02:57:22 +02:00
|
|
|
* this case work the same as the normal assignment case;
|
|
|
|
* note the possible free of newval below.
|
2006-08-14 04:27:27 +02:00
|
|
|
*/
|
2007-09-10 02:57:22 +02:00
|
|
|
if (conf->reset_val == NULL)
|
|
|
|
newval = NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
newval = guc_strdup(elevel, conf->reset_val);
|
|
|
|
if (newval == NULL)
|
|
|
|
return false;
|
|
|
|
}
|
2006-08-14 04:27:27 +02:00
|
|
|
source = conf->gen.reset_source;
|
|
|
|
}
|
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
if (conf->assign_hook && newval)
|
2006-08-14 04:27:27 +02:00
|
|
|
{
|
|
|
|
const char *hookresult;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the hook ereports, we have to make sure we free
|
|
|
|
* newval, else it will be a permanent memory leak.
|
|
|
|
*/
|
|
|
|
hookresult = call_string_assign_hook(conf->assign_hook,
|
|
|
|
newval,
|
|
|
|
changeVal,
|
|
|
|
source);
|
|
|
|
if (hookresult == NULL)
|
|
|
|
{
|
|
|
|
free(newval);
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("invalid value for parameter \"%s\": \"%s\"",
|
|
|
|
name, value ? value : "")));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (hookresult != newval)
|
|
|
|
{
|
|
|
|
free(newval);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Having to cast away const here is annoying, but the
|
|
|
|
* alternative is to declare assign_hooks as returning
|
|
|
|
* char*, which would mean they'd have to cast away
|
|
|
|
* const, or as both taking and returning char*, which
|
|
|
|
* doesn't seem attractive either --- we don't want
|
|
|
|
* them to scribble on the passed str.
|
|
|
|
*/
|
|
|
|
newval = (char *) hookresult;
|
|
|
|
}
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2003-09-01 06:15:51 +02:00
|
|
|
if (changeVal || makeDefault)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2004-07-01 02:52:04 +02:00
|
|
|
/* Save old value to support transaction abort */
|
|
|
|
if (!makeDefault)
|
2007-09-11 02:06:42 +02:00
|
|
|
push_old_value(&conf->gen, action);
|
2003-09-01 06:15:51 +02:00
|
|
|
if (changeVal)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2004-07-01 02:52:04 +02:00
|
|
|
set_string_field(conf, conf->variable, newval);
|
2002-05-17 03:19:19 +02:00
|
|
|
conf->gen.source = source;
|
|
|
|
}
|
|
|
|
if (makeDefault)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
GucStack *stack;
|
2004-07-01 02:52:04 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
if (conf->gen.reset_source <= source)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
2004-07-01 02:52:04 +02:00
|
|
|
set_string_field(conf, &conf->reset_val, newval);
|
2002-05-17 03:19:19 +02:00
|
|
|
conf->gen.reset_source = source;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
2004-07-01 02:52:04 +02:00
|
|
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
2001-06-07 06:50:57 +02:00
|
|
|
{
|
2004-07-01 02:52:04 +02:00
|
|
|
if (stack->source <= source)
|
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
set_string_field(conf, &stack->prior.stringval,
|
2004-07-01 02:52:04 +02:00
|
|
|
newval);
|
|
|
|
stack->source = source;
|
|
|
|
}
|
2001-06-07 06:50:57 +02:00
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
/* Perhaps we didn't install newval anywhere */
|
2007-09-10 02:57:22 +02:00
|
|
|
if (newval && !string_field_used(conf, newval))
|
2002-05-17 03:19:19 +02:00
|
|
|
free(newval);
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2007-09-10 02:57:22 +02:00
|
|
|
else if (newval)
|
2006-08-12 06:12:41 +02:00
|
|
|
free(newval);
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
2000-05-31 02:28:42 +02:00
|
|
|
}
|
2008-03-10 13:55:13 +01:00
|
|
|
case PGC_ENUM:
|
|
|
|
{
|
|
|
|
struct config_enum *conf = (struct config_enum *) record;
|
|
|
|
int newval;
|
|
|
|
|
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
if (!config_enum_lookup_name(conf, value, &newval))
|
|
|
|
{
|
|
|
|
char *hintmsg = config_enum_get_options(conf, "Available values: ", ".");
|
|
|
|
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("invalid value for parameter \"%s\": \"%s\"",
|
|
|
|
name, value),
|
|
|
|
hintmsg ? errhint(hintmsg) : 0));
|
|
|
|
|
|
|
|
if (hintmsg)
|
|
|
|
pfree(hintmsg);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (source == PGC_S_DEFAULT)
|
|
|
|
newval = conf->boot_val;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
newval = conf->reset_val;
|
|
|
|
source = conf->gen.reset_source;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (conf->assign_hook)
|
|
|
|
if (!(*conf->assign_hook) (newval, changeVal, source))
|
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("invalid value for parameter \"%s\": \"%d\"",
|
|
|
|
name, newval)));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (changeVal || makeDefault)
|
|
|
|
{
|
|
|
|
/* Save old value to support transaction abort */
|
|
|
|
if (!makeDefault)
|
|
|
|
push_old_value(&conf->gen, action);
|
|
|
|
if (changeVal)
|
|
|
|
{
|
|
|
|
*conf->variable = newval;
|
|
|
|
conf->gen.source = source;
|
|
|
|
}
|
|
|
|
if (makeDefault)
|
|
|
|
{
|
|
|
|
GucStack *stack;
|
|
|
|
|
|
|
|
if (conf->gen.reset_source <= source)
|
|
|
|
{
|
|
|
|
conf->reset_val = newval;
|
|
|
|
conf->gen.reset_source = source;
|
|
|
|
}
|
|
|
|
for (stack = conf->gen.stack; stack; stack = stack->prev)
|
|
|
|
{
|
|
|
|
if (stack->source <= source)
|
|
|
|
{
|
|
|
|
stack->prior.enumval = newval;
|
|
|
|
stack->source = source;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2001-01-24 19:37:31 +01:00
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2003-09-01 06:15:51 +02:00
|
|
|
if (changeVal && (record->flags & GUC_REPORT))
|
2003-07-04 18:41:22 +02:00
|
|
|
ReportGUCOption(record);
|
2003-04-25 21:45:10 +02:00
|
|
|
|
2000-05-31 02:28:42 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set a config option to the given value. See also set_config_option,
|
2002-09-04 22:31:48 +02:00
|
|
|
* this is just the wrapper to be called from outside GUC. NB: this
|
2002-05-17 03:19:19 +02:00
|
|
|
* is used only for non-transactional operations.
|
2000-05-31 02:28:42 +02:00
|
|
|
*/
|
|
|
|
void
|
2001-06-13 00:54:06 +02:00
|
|
|
SetConfigOption(const char *name, const char *value,
|
2002-02-23 02:31:37 +01:00
|
|
|
GucContext context, GucSource source)
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2007-09-11 02:06:42 +02:00
|
|
|
(void) set_config_option(name, value, context, source,
|
|
|
|
GUC_ACTION_SET, true);
|
2000-05-31 02:28:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2002-05-17 03:19:19 +02:00
|
|
|
* Fetch the current value of the option `name'. If the option doesn't exist,
|
2003-07-25 22:18:01 +02:00
|
|
|
* throw an ereport and don't return.
|
2000-05-31 02:28:42 +02:00
|
|
|
*
|
|
|
|
* The string is *not* allocated for modification and is really only
|
|
|
|
* valid until the next call to configuration related functions.
|
|
|
|
*/
|
|
|
|
const char *
|
2001-03-22 05:01:46 +01:00
|
|
|
GetConfigOption(const char *name)
|
2000-05-31 02:28:42 +02:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
struct config_generic *record;
|
2000-05-31 02:28:42 +02:00
|
|
|
static char buffer[256];
|
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
record = find_option(name, false, ERROR);
|
2002-05-17 03:19:19 +02:00
|
|
|
if (record == NULL)
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
2005-10-15 04:49:52 +02:00
|
|
|
errmsg("unrecognized configuration parameter \"%s\"", name)));
|
2004-10-22 21:48:19 +02:00
|
|
|
if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("must be superuser to examine \"%s\"", name)));
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
switch (record->vartype)
|
2001-01-24 19:37:31 +01:00
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
2001-03-22 05:01:46 +01:00
|
|
|
return *((struct config_bool *) record)->variable ? "on" : "off";
|
2000-05-31 02:28:42 +02:00
|
|
|
|
2001-01-24 19:37:31 +01:00
|
|
|
case PGC_INT:
|
2001-06-13 00:54:06 +02:00
|
|
|
snprintf(buffer, sizeof(buffer), "%d",
|
|
|
|
*((struct config_int *) record)->variable);
|
2000-05-31 02:28:42 +02:00
|
|
|
return buffer;
|
|
|
|
|
2001-01-24 19:37:31 +01:00
|
|
|
case PGC_REAL:
|
2001-06-13 00:54:06 +02:00
|
|
|
snprintf(buffer, sizeof(buffer), "%g",
|
|
|
|
*((struct config_real *) record)->variable);
|
2000-05-31 02:28:42 +02:00
|
|
|
return buffer;
|
|
|
|
|
|
|
|
case PGC_STRING:
|
2001-03-22 05:01:46 +01:00
|
|
|
return *((struct config_string *) record)->variable;
|
2008-03-10 13:55:13 +01:00
|
|
|
|
|
|
|
case PGC_ENUM:
|
|
|
|
return config_enum_lookup_value((struct config_enum *) record,
|
|
|
|
*((struct config_enum *) record)->variable);
|
2001-01-24 19:37:31 +01:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2000-07-03 22:46:10 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
|
|
|
* Get the RESET value associated with the given option.
|
2007-09-10 02:57:22 +02:00
|
|
|
*
|
|
|
|
* Note: this is not re-entrant, due to use of static result buffer;
|
|
|
|
* not to mention that a string variable could have its reset_val changed.
|
|
|
|
* Beware of assuming the result value is good for very long.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
|
|
|
const char *
|
|
|
|
GetConfigOptionResetString(const char *name)
|
2001-06-07 06:50:57 +02:00
|
|
|
{
|
2002-05-17 03:19:19 +02:00
|
|
|
struct config_generic *record;
|
|
|
|
static char buffer[256];
|
2001-06-07 06:50:57 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
record = find_option(name, false, ERROR);
|
2002-05-17 03:19:19 +02:00
|
|
|
if (record == NULL)
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
2005-10-15 04:49:52 +02:00
|
|
|
errmsg("unrecognized configuration parameter \"%s\"", name)));
|
2004-10-22 21:48:19 +02:00
|
|
|
if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("must be superuser to examine \"%s\"", name)));
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
switch (record->vartype)
|
2001-06-07 06:50:57 +02:00
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
2002-05-17 03:19:19 +02:00
|
|
|
return ((struct config_bool *) record)->reset_val ? "on" : "off";
|
2001-06-18 18:14:44 +02:00
|
|
|
|
2001-06-07 06:50:57 +02:00
|
|
|
case PGC_INT:
|
2001-06-13 00:54:06 +02:00
|
|
|
snprintf(buffer, sizeof(buffer), "%d",
|
2002-05-17 03:19:19 +02:00
|
|
|
((struct config_int *) record)->reset_val);
|
|
|
|
return buffer;
|
2001-06-07 06:50:57 +02:00
|
|
|
|
|
|
|
case PGC_REAL:
|
2001-06-13 00:54:06 +02:00
|
|
|
snprintf(buffer, sizeof(buffer), "%g",
|
2002-05-17 03:19:19 +02:00
|
|
|
((struct config_real *) record)->reset_val);
|
|
|
|
return buffer;
|
2001-06-07 06:50:57 +02:00
|
|
|
|
|
|
|
case PGC_STRING:
|
2002-05-17 03:19:19 +02:00
|
|
|
return ((struct config_string *) record)->reset_val;
|
2008-03-10 13:55:13 +01:00
|
|
|
|
|
|
|
case PGC_ENUM:
|
|
|
|
return config_enum_lookup_value((struct config_enum *) record,
|
|
|
|
((struct config_enum *) record)->reset_val);
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-06-07 06:50:57 +02:00
|
|
|
|
2004-11-24 20:51:05 +01:00
|
|
|
/*
|
|
|
|
* Detect whether the given configuration option can only be set by
|
|
|
|
* a superuser.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
IsSuperuserConfigOption(const char *name)
|
|
|
|
{
|
|
|
|
struct config_generic *record;
|
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
record = find_option(name, false, ERROR);
|
2004-11-24 20:51:05 +01:00
|
|
|
/* On an unrecognized name, don't error, just return false. */
|
|
|
|
if (record == NULL)
|
|
|
|
return false;
|
|
|
|
return (record->context == PGC_SUSET);
|
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
|
2007-12-28 01:23:23 +01:00
|
|
|
/*
|
|
|
|
* GUC_complaint_elevel
|
|
|
|
* Get the ereport error level to use in an assign_hook's error report.
|
|
|
|
*
|
|
|
|
* This should be used by assign hooks that want to emit a custom error
|
|
|
|
* report (in addition to the generic "invalid value for option FOO" that
|
|
|
|
* guc.c will provide). Note that the result might be ERROR or a lower
|
|
|
|
* level, so the caller must be prepared for control to return from ereport,
|
|
|
|
* or not. If control does return, return false/NULL from the hook function.
|
|
|
|
*
|
|
|
|
* At some point it'd be nice to replace this with a mechanism that allows
|
|
|
|
* the custom message to become the DETAIL line of guc.c's generic message.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
GUC_complaint_elevel(GucSource source)
|
|
|
|
{
|
|
|
|
int elevel;
|
|
|
|
|
|
|
|
if (source == PGC_S_FILE)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* To avoid cluttering the log, only the postmaster bleats loudly
|
|
|
|
* about problems with the config file.
|
|
|
|
*/
|
|
|
|
elevel = IsUnderPostmaster ? DEBUG3 : LOG;
|
|
|
|
}
|
2008-01-14 20:18:53 +01:00
|
|
|
else if (source == PGC_S_OVERRIDE)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* If we're a postmaster child, this is probably "undo" during
|
|
|
|
* transaction abort, so we don't want to clutter the log. There's
|
|
|
|
* a small chance of a real problem with an OVERRIDE setting,
|
|
|
|
* though, so suppressing the message entirely wouldn't be desirable.
|
|
|
|
*/
|
|
|
|
elevel = IsUnderPostmaster ? DEBUG5 : LOG;
|
|
|
|
}
|
2007-12-28 01:23:23 +01:00
|
|
|
else if (source < PGC_S_INTERACTIVE)
|
|
|
|
elevel = LOG;
|
|
|
|
else
|
|
|
|
elevel = ERROR;
|
|
|
|
|
|
|
|
return elevel;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
|
|
|
* flatten_set_variable_args
|
|
|
|
* Given a parsenode List as emitted by the grammar for SET,
|
|
|
|
* convert to the flat string representation used by GUC.
|
|
|
|
*
|
|
|
|
* We need to be told the name of the variable the args are for, because
|
|
|
|
* the flattening rules vary (ugh).
|
|
|
|
*
|
2007-09-03 20:46:30 +02:00
|
|
|
* The result is NULL if args is NIL (ie, SET ... TO DEFAULT), otherwise
|
2002-05-17 03:19:19 +02:00
|
|
|
* a palloc'd string.
|
|
|
|
*/
|
2007-09-03 20:46:30 +02:00
|
|
|
static char *
|
2002-05-17 03:19:19 +02:00
|
|
|
flatten_set_variable_args(const char *name, List *args)
|
|
|
|
{
|
|
|
|
struct config_generic *record;
|
|
|
|
int flags;
|
|
|
|
StringInfoData buf;
|
2004-05-26 06:41:50 +02:00
|
|
|
ListCell *l;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2007-09-03 20:46:30 +02:00
|
|
|
/* Fast path if just DEFAULT */
|
2002-05-17 03:19:19 +02:00
|
|
|
if (args == NIL)
|
|
|
|
return NULL;
|
|
|
|
|
2002-09-12 16:03:45 +02:00
|
|
|
/* Else get flags for the variable */
|
2007-09-10 02:57:22 +02:00
|
|
|
record = find_option(name, true, ERROR);
|
2002-05-17 03:19:19 +02:00
|
|
|
if (record == NULL)
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
2005-10-15 04:49:52 +02:00
|
|
|
errmsg("unrecognized configuration parameter \"%s\"", name)));
|
2002-09-12 16:03:45 +02:00
|
|
|
|
|
|
|
flags = record->flags;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
/* Complain if list input and non-list variable */
|
|
|
|
if ((flags & GUC_LIST_INPUT) == 0 &&
|
2004-05-26 06:41:50 +02:00
|
|
|
list_length(args) != 1)
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("SET %s takes only one argument", name)));
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
initStringInfo(&buf);
|
|
|
|
|
|
|
|
foreach(l, args)
|
|
|
|
{
|
|
|
|
A_Const *arg = (A_Const *) lfirst(l);
|
|
|
|
char *val;
|
|
|
|
|
2004-05-26 06:41:50 +02:00
|
|
|
if (l != list_head(args))
|
2002-05-17 03:19:19 +02:00
|
|
|
appendStringInfo(&buf, ", ");
|
|
|
|
|
|
|
|
if (!IsA(arg, A_Const))
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(arg));
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
switch (nodeTag(&arg->val))
|
|
|
|
{
|
|
|
|
case T_Integer:
|
|
|
|
appendStringInfo(&buf, "%ld", intVal(&arg->val));
|
|
|
|
break;
|
|
|
|
case T_Float:
|
|
|
|
/* represented as a string, so just copy it */
|
2004-01-31 06:09:41 +01:00
|
|
|
appendStringInfoString(&buf, strVal(&arg->val));
|
2002-05-17 03:19:19 +02:00
|
|
|
break;
|
|
|
|
case T_String:
|
|
|
|
val = strVal(&arg->val);
|
|
|
|
if (arg->typename != NULL)
|
|
|
|
{
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Must be a ConstInterval argument for TIME ZONE. Coerce
|
|
|
|
* to interval and back to normalize the value and account
|
|
|
|
* for any typmod.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
2007-11-11 20:22:49 +01:00
|
|
|
Oid typoid;
|
2006-12-30 22:21:56 +01:00
|
|
|
int32 typmod;
|
2005-10-15 04:49:52 +02:00
|
|
|
Datum interval;
|
2002-09-04 22:31:48 +02:00
|
|
|
char *intervalout;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2007-11-11 20:22:49 +01:00
|
|
|
typoid = typenameTypeId(NULL, arg->typename, &typmod);
|
|
|
|
Assert(typoid == INTERVALOID);
|
2006-12-30 22:21:56 +01:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
interval =
|
2005-10-15 04:49:52 +02:00
|
|
|
DirectFunctionCall3(interval_in,
|
|
|
|
CStringGetDatum(val),
|
|
|
|
ObjectIdGetDatum(InvalidOid),
|
2006-12-30 22:21:56 +01:00
|
|
|
Int32GetDatum(typmod));
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
intervalout =
|
2005-05-01 20:56:19 +02:00
|
|
|
DatumGetCString(DirectFunctionCall1(interval_out,
|
|
|
|
interval));
|
2002-05-17 03:19:19 +02:00
|
|
|
appendStringInfo(&buf, "INTERVAL '%s'", intervalout);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Plain string literal or identifier. For quote mode,
|
|
|
|
* quote it if it's not a vanilla identifier.
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
|
|
|
if (flags & GUC_LIST_QUOTE)
|
2004-01-31 06:09:41 +01:00
|
|
|
appendStringInfoString(&buf, quote_identifier(val));
|
2002-05-17 03:19:19 +02:00
|
|
|
else
|
2004-01-31 06:09:41 +01:00
|
|
|
appendStringInfoString(&buf, val);
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(ERROR, "unrecognized node type: %d",
|
|
|
|
(int) nodeTag(&arg->val));
|
2002-05-17 03:19:19 +02:00
|
|
|
break;
|
|
|
|
}
|
2001-06-07 06:50:57 +02:00
|
|
|
}
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
return buf.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SET command
|
|
|
|
*/
|
|
|
|
void
|
2007-09-03 20:46:30 +02:00
|
|
|
ExecSetVariableStmt(VariableSetStmt *stmt)
|
|
|
|
{
|
2007-11-15 22:14:46 +01:00
|
|
|
GucAction action = stmt->is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET;
|
2007-09-11 02:06:42 +02:00
|
|
|
|
2007-09-03 20:46:30 +02:00
|
|
|
switch (stmt->kind)
|
|
|
|
{
|
|
|
|
case VAR_SET_VALUE:
|
|
|
|
case VAR_SET_CURRENT:
|
|
|
|
set_config_option(stmt->name,
|
|
|
|
ExtractSetVariableArgs(stmt),
|
|
|
|
(superuser() ? PGC_SUSET : PGC_USERSET),
|
|
|
|
PGC_S_SESSION,
|
2007-09-11 02:06:42 +02:00
|
|
|
action,
|
2007-09-03 20:46:30 +02:00
|
|
|
true);
|
|
|
|
break;
|
|
|
|
case VAR_SET_MULTI:
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2007-09-03 20:46:30 +02:00
|
|
|
/*
|
2007-11-15 22:14:46 +01:00
|
|
|
* Special case for special SQL syntax that effectively sets more
|
|
|
|
* than one variable per statement.
|
2007-09-03 20:46:30 +02:00
|
|
|
*/
|
|
|
|
if (strcmp(stmt->name, "TRANSACTION") == 0)
|
|
|
|
{
|
|
|
|
ListCell *head;
|
|
|
|
|
|
|
|
foreach(head, stmt->args)
|
|
|
|
{
|
|
|
|
DefElem *item = (DefElem *) lfirst(head);
|
|
|
|
|
|
|
|
if (strcmp(item->defname, "transaction_isolation") == 0)
|
|
|
|
SetPGVariable("transaction_isolation",
|
|
|
|
list_make1(item->arg), stmt->is_local);
|
|
|
|
else if (strcmp(item->defname, "transaction_read_only") == 0)
|
|
|
|
SetPGVariable("transaction_read_only",
|
|
|
|
list_make1(item->arg), stmt->is_local);
|
|
|
|
else
|
|
|
|
elog(ERROR, "unexpected SET TRANSACTION element: %s",
|
|
|
|
item->defname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strcmp(stmt->name, "SESSION CHARACTERISTICS") == 0)
|
|
|
|
{
|
|
|
|
ListCell *head;
|
|
|
|
|
|
|
|
foreach(head, stmt->args)
|
|
|
|
{
|
|
|
|
DefElem *item = (DefElem *) lfirst(head);
|
|
|
|
|
|
|
|
if (strcmp(item->defname, "transaction_isolation") == 0)
|
|
|
|
SetPGVariable("default_transaction_isolation",
|
|
|
|
list_make1(item->arg), stmt->is_local);
|
|
|
|
else if (strcmp(item->defname, "transaction_read_only") == 0)
|
|
|
|
SetPGVariable("default_transaction_read_only",
|
|
|
|
list_make1(item->arg), stmt->is_local);
|
|
|
|
else
|
|
|
|
elog(ERROR, "unexpected SET SESSION element: %s",
|
|
|
|
item->defname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
elog(ERROR, "unexpected SET MULTI element: %s",
|
|
|
|
stmt->name);
|
|
|
|
break;
|
|
|
|
case VAR_SET_DEFAULT:
|
|
|
|
case VAR_RESET:
|
|
|
|
set_config_option(stmt->name,
|
|
|
|
NULL,
|
|
|
|
(superuser() ? PGC_SUSET : PGC_USERSET),
|
|
|
|
PGC_S_SESSION,
|
2007-09-11 02:06:42 +02:00
|
|
|
action,
|
2007-09-03 20:46:30 +02:00
|
|
|
true);
|
|
|
|
break;
|
|
|
|
case VAR_RESET_ALL:
|
|
|
|
ResetAllOptions();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the value to assign for a VariableSetStmt, or NULL if it's RESET.
|
|
|
|
* The result is palloc'd.
|
|
|
|
*
|
|
|
|
* This is exported for use by actions such as ALTER ROLE SET.
|
|
|
|
*/
|
|
|
|
char *
|
|
|
|
ExtractSetVariableArgs(VariableSetStmt *stmt)
|
|
|
|
{
|
|
|
|
switch (stmt->kind)
|
|
|
|
{
|
|
|
|
case VAR_SET_VALUE:
|
|
|
|
return flatten_set_variable_args(stmt->name, stmt->args);
|
|
|
|
case VAR_SET_CURRENT:
|
|
|
|
return GetConfigOptionByName(stmt->name, NULL);
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SetPGVariable - SET command exported as an easily-C-callable function.
|
|
|
|
*
|
|
|
|
* This provides access to SET TO value, as well as SET TO DEFAULT (expressed
|
|
|
|
* by passing args == NIL), but not SET FROM CURRENT functionality.
|
|
|
|
*/
|
|
|
|
void
|
2002-05-17 03:19:19 +02:00
|
|
|
SetPGVariable(const char *name, List *args, bool is_local)
|
|
|
|
{
|
|
|
|
char *argstring = flatten_set_variable_args(name, args);
|
|
|
|
|
|
|
|
/* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */
|
|
|
|
set_config_option(name,
|
|
|
|
argstring,
|
|
|
|
(superuser() ? PGC_SUSET : PGC_USERSET),
|
|
|
|
PGC_S_SESSION,
|
2007-09-11 02:06:42 +02:00
|
|
|
is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
|
2002-05-17 03:19:19 +02:00
|
|
|
true);
|
|
|
|
}
|
|
|
|
|
2002-07-20 07:49:28 +02:00
|
|
|
/*
|
|
|
|
* SET command wrapped as a SQL callable function.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
set_config_by_name(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
char *name;
|
|
|
|
char *value;
|
|
|
|
char *new_value;
|
|
|
|
bool is_local;
|
|
|
|
text *result_text;
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
if (PG_ARGISNULL(0))
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
2003-09-25 08:58:07 +02:00
|
|
|
errmsg("SET requires parameter name")));
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
/* Get the GUC variable name */
|
2002-07-20 17:12:56 +02:00
|
|
|
name = DatumGetCString(DirectFunctionCall1(textout, PG_GETARG_DATUM(0)));
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
/* Get the desired value or set to NULL for a reset request */
|
|
|
|
if (PG_ARGISNULL(1))
|
|
|
|
value = NULL;
|
|
|
|
else
|
2002-07-20 17:12:56 +02:00
|
|
|
value = DatumGetCString(DirectFunctionCall1(textout, PG_GETARG_DATUM(1)));
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Get the desired state of is_local. Default to false if provided value
|
|
|
|
* is NULL
|
2002-07-20 07:49:28 +02:00
|
|
|
*/
|
|
|
|
if (PG_ARGISNULL(2))
|
|
|
|
is_local = false;
|
|
|
|
else
|
|
|
|
is_local = PG_GETARG_BOOL(2);
|
|
|
|
|
|
|
|
/* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */
|
|
|
|
set_config_option(name,
|
|
|
|
value,
|
|
|
|
(superuser() ? PGC_SUSET : PGC_USERSET),
|
|
|
|
PGC_S_SESSION,
|
2007-09-11 02:06:42 +02:00
|
|
|
is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
|
2002-07-20 07:49:28 +02:00
|
|
|
true);
|
|
|
|
|
|
|
|
/* get the new current value */
|
2002-07-20 17:12:56 +02:00
|
|
|
new_value = GetConfigOptionByName(name, NULL);
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
/* Convert return string to text */
|
|
|
|
result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(new_value)));
|
|
|
|
|
|
|
|
/* return it */
|
|
|
|
PG_RETURN_TEXT_P(result_text);
|
|
|
|
}
|
|
|
|
|
2007-09-03 20:46:30 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
/*
|
|
|
|
* Common code for DefineCustomXXXVariable subroutines: allocate the
|
|
|
|
* new variable's config struct and fill in generic fields.
|
|
|
|
*/
|
|
|
|
static struct config_generic *
|
|
|
|
init_custom_variable(const char *name,
|
|
|
|
const char *short_desc,
|
|
|
|
const char *long_desc,
|
|
|
|
GucContext context,
|
|
|
|
enum config_type type,
|
|
|
|
size_t sz)
|
|
|
|
{
|
|
|
|
struct config_generic *gen;
|
|
|
|
|
|
|
|
gen = (struct config_generic *) guc_malloc(ERROR, sz);
|
|
|
|
memset(gen, 0, sz);
|
|
|
|
|
|
|
|
gen->name = guc_strdup(ERROR, name);
|
|
|
|
gen->context = context;
|
|
|
|
gen->group = CUSTOM_OPTIONS;
|
|
|
|
gen->short_desc = short_desc;
|
|
|
|
gen->long_desc = long_desc;
|
|
|
|
gen->vartype = type;
|
|
|
|
|
|
|
|
return gen;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Common code for DefineCustomXXXVariable subroutines: insert the new
|
|
|
|
* variable into the GUC variable array, replacing any placeholder.
|
|
|
|
*/
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
static void
|
2007-11-15 22:14:46 +01:00
|
|
|
define_custom_variable(struct config_generic * variable)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
const char *name = variable->name;
|
|
|
|
const char **nameAddr = &name;
|
|
|
|
const char *value;
|
|
|
|
struct config_string *pHolder;
|
2007-09-10 02:57:22 +02:00
|
|
|
struct config_generic **res;
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
res = (struct config_generic **) bsearch((void *) &nameAddr,
|
|
|
|
(void *) guc_variables,
|
|
|
|
num_guc_variables,
|
|
|
|
sizeof(struct config_generic *),
|
|
|
|
guc_var_compare);
|
2004-08-29 07:07:03 +02:00
|
|
|
if (res == NULL)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2007-09-10 02:57:22 +02:00
|
|
|
/* No placeholder to replace, so just add it */
|
2004-07-06 01:14:14 +02:00
|
|
|
add_guc_variable(variable, ERROR);
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
/*
|
|
|
|
* This better be a placeholder
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
*/
|
2004-08-29 07:07:03 +02:00
|
|
|
if (((*res)->flags & GUC_CUSTOM_PLACEHOLDER) == 0)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INTERNAL_ERROR),
|
|
|
|
errmsg("attempt to redefine parameter \"%s\"", name)));
|
2004-07-01 02:52:04 +02:00
|
|
|
|
|
|
|
Assert((*res)->vartype == PGC_STRING);
|
2007-09-10 02:57:22 +02:00
|
|
|
pHolder = (struct config_string *) (*res);
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
/*
|
2007-11-15 22:14:46 +01:00
|
|
|
* Replace the placeholder. We aren't changing the name, so no re-sorting
|
|
|
|
* is necessary
|
2007-09-10 02:57:22 +02:00
|
|
|
*/
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
*res = variable;
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Assign the string value stored in the placeholder to the real variable.
|
2004-07-01 02:52:04 +02:00
|
|
|
*
|
|
|
|
* XXX this is not really good enough --- it should be a nontransactional
|
|
|
|
* assignment, since we don't want it to roll back if the current xact
|
|
|
|
* fails later.
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
*/
|
2007-09-10 02:57:22 +02:00
|
|
|
value = *pHolder->variable;
|
|
|
|
|
|
|
|
if (value)
|
|
|
|
set_config_option(name, value,
|
|
|
|
pHolder->gen.context, pHolder->gen.source,
|
2007-09-11 02:06:42 +02:00
|
|
|
GUC_ACTION_SET, true);
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
/*
|
|
|
|
* Free up as much as we conveniently can of the placeholder structure
|
|
|
|
* (this neglects any stack items...)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
*/
|
2004-07-01 02:52:04 +02:00
|
|
|
set_string_field(pHolder, pHolder->variable, NULL);
|
|
|
|
set_string_field(pHolder, &pHolder->reset_val, NULL);
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
|
|
|
free(pHolder);
|
|
|
|
}
|
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
void
|
2005-07-26 00:12:34 +02:00
|
|
|
DefineCustomBoolVariable(const char *name,
|
2004-08-29 07:07:03 +02:00
|
|
|
const char *short_desc,
|
|
|
|
const char *long_desc,
|
|
|
|
bool *valueAddr,
|
|
|
|
GucContext context,
|
|
|
|
GucBoolAssignHook assign_hook,
|
|
|
|
GucShowHook show_hook)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2007-09-10 02:57:22 +02:00
|
|
|
struct config_bool *var;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
var = (struct config_bool *)
|
|
|
|
init_custom_variable(name, short_desc, long_desc, context,
|
|
|
|
PGC_BOOL, sizeof(struct config_bool));
|
2004-08-29 07:07:03 +02:00
|
|
|
var->variable = valueAddr;
|
2007-09-10 02:57:22 +02:00
|
|
|
var->boot_val = *valueAddr;
|
2004-08-29 07:07:03 +02:00
|
|
|
var->reset_val = *valueAddr;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
var->assign_hook = assign_hook;
|
2004-08-29 07:07:03 +02:00
|
|
|
var->show_hook = show_hook;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
define_custom_variable(&var->gen);
|
|
|
|
}
|
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
void
|
2005-07-26 00:12:34 +02:00
|
|
|
DefineCustomIntVariable(const char *name,
|
2004-08-29 07:07:03 +02:00
|
|
|
const char *short_desc,
|
|
|
|
const char *long_desc,
|
|
|
|
int *valueAddr,
|
2005-03-25 17:17:28 +01:00
|
|
|
int minValue,
|
|
|
|
int maxValue,
|
2004-08-29 07:07:03 +02:00
|
|
|
GucContext context,
|
|
|
|
GucIntAssignHook assign_hook,
|
|
|
|
GucShowHook show_hook)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2007-09-10 02:57:22 +02:00
|
|
|
struct config_int *var;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
var = (struct config_int *)
|
|
|
|
init_custom_variable(name, short_desc, long_desc, context,
|
|
|
|
PGC_INT, sizeof(struct config_int));
|
2004-08-29 07:07:03 +02:00
|
|
|
var->variable = valueAddr;
|
2007-09-10 02:57:22 +02:00
|
|
|
var->boot_val = *valueAddr;
|
2004-08-29 07:07:03 +02:00
|
|
|
var->reset_val = *valueAddr;
|
2005-03-25 17:17:28 +01:00
|
|
|
var->min = minValue;
|
|
|
|
var->max = maxValue;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
var->assign_hook = assign_hook;
|
2004-08-29 07:07:03 +02:00
|
|
|
var->show_hook = show_hook;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
define_custom_variable(&var->gen);
|
|
|
|
}
|
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
void
|
2005-07-26 00:12:34 +02:00
|
|
|
DefineCustomRealVariable(const char *name,
|
2004-08-29 07:07:03 +02:00
|
|
|
const char *short_desc,
|
|
|
|
const char *long_desc,
|
|
|
|
double *valueAddr,
|
2005-03-25 17:17:28 +01:00
|
|
|
double minValue,
|
|
|
|
double maxValue,
|
2004-08-29 07:07:03 +02:00
|
|
|
GucContext context,
|
|
|
|
GucRealAssignHook assign_hook,
|
|
|
|
GucShowHook show_hook)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2007-09-10 02:57:22 +02:00
|
|
|
struct config_real *var;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
var = (struct config_real *)
|
|
|
|
init_custom_variable(name, short_desc, long_desc, context,
|
|
|
|
PGC_REAL, sizeof(struct config_real));
|
2004-08-29 07:07:03 +02:00
|
|
|
var->variable = valueAddr;
|
2007-09-10 02:57:22 +02:00
|
|
|
var->boot_val = *valueAddr;
|
2004-08-29 07:07:03 +02:00
|
|
|
var->reset_val = *valueAddr;
|
2005-03-25 17:17:28 +01:00
|
|
|
var->min = minValue;
|
|
|
|
var->max = maxValue;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
var->assign_hook = assign_hook;
|
2004-08-29 07:07:03 +02:00
|
|
|
var->show_hook = show_hook;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
define_custom_variable(&var->gen);
|
|
|
|
}
|
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
void
|
2005-07-26 00:12:34 +02:00
|
|
|
DefineCustomStringVariable(const char *name,
|
2004-08-29 07:07:03 +02:00
|
|
|
const char *short_desc,
|
|
|
|
const char *long_desc,
|
|
|
|
char **valueAddr,
|
|
|
|
GucContext context,
|
|
|
|
GucStringAssignHook assign_hook,
|
|
|
|
GucShowHook show_hook)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2007-09-10 02:57:22 +02:00
|
|
|
struct config_string *var;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
var = (struct config_string *)
|
|
|
|
init_custom_variable(name, short_desc, long_desc, context,
|
|
|
|
PGC_STRING, sizeof(struct config_string));
|
2004-08-29 07:07:03 +02:00
|
|
|
var->variable = valueAddr;
|
2007-09-10 02:57:22 +02:00
|
|
|
var->boot_val = *valueAddr;
|
|
|
|
/* we could probably do without strdup, but keep it like normal case */
|
|
|
|
if (var->boot_val)
|
|
|
|
var->reset_val = guc_strdup(ERROR, var->boot_val);
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
var->assign_hook = assign_hook;
|
2004-08-29 07:07:03 +02:00
|
|
|
var->show_hook = show_hook;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
define_custom_variable(&var->gen);
|
|
|
|
}
|
|
|
|
|
2004-10-11 01:37:45 +02:00
|
|
|
void
|
2004-08-29 07:07:03 +02:00
|
|
|
EmitWarningsOnPlaceholders(const char *className)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
struct config_generic **vars = guc_variables;
|
|
|
|
struct config_generic **last = vars + num_guc_variables;
|
|
|
|
|
|
|
|
int nameLen = strlen(className);
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
while (vars < last)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
struct config_generic *var = *vars++;
|
|
|
|
|
|
|
|
if ((var->flags & GUC_CUSTOM_PLACEHOLDER) != 0 &&
|
|
|
|
strncmp(className, var->name, nameLen) == 0 &&
|
|
|
|
var->name[nameLen] == GUC_QUALIFIER_SEPARATOR)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
|
|
|
ereport(INFO,
|
2004-08-29 07:07:03 +02:00
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("unrecognized configuration parameter \"%s\"", var->name)));
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
|
|
|
* SHOW command
|
|
|
|
*/
|
|
|
|
void
|
2003-05-06 22:26:28 +02:00
|
|
|
GetPGVariable(const char *name, DestReceiver *dest)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2007-09-10 02:57:22 +02:00
|
|
|
if (guc_name_compare(name, "all") == 0)
|
2003-05-06 22:26:28 +02:00
|
|
|
ShowAllGUCConfig(dest);
|
2002-05-17 03:19:19 +02:00
|
|
|
else
|
2003-05-06 22:26:28 +02:00
|
|
|
ShowGUCConfigOption(name, dest);
|
|
|
|
}
|
|
|
|
|
|
|
|
TupleDesc
|
|
|
|
GetPGVariableResultDesc(const char *name)
|
|
|
|
{
|
|
|
|
TupleDesc tupdesc;
|
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
if (guc_name_compare(name, "all") == 0)
|
2003-05-06 22:26:28 +02:00
|
|
|
{
|
2005-06-14 22:42:53 +02:00
|
|
|
/* need a tuple descriptor representing three TEXT columns */
|
|
|
|
tupdesc = CreateTemplateTupleDesc(3, false);
|
2003-05-06 22:26:28 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2003-05-06 22:26:28 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2005-06-14 22:42:53 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
|
|
|
|
TEXTOID, -1, 0);
|
|
|
|
|
2003-05-06 22:26:28 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const char *varname;
|
|
|
|
|
|
|
|
/* Get the canonical spelling of name */
|
|
|
|
(void) GetConfigOptionByName(name, &varname);
|
|
|
|
|
|
|
|
/* need a tuple descriptor representing a single TEXT column */
|
|
|
|
tupdesc = CreateTemplateTupleDesc(1, false);
|
2006-08-14 04:27:27 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
|
|
|
|
TEXTOID, -1, 0);
|
2003-05-06 22:26:28 +02:00
|
|
|
}
|
|
|
|
return tupdesc;
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SHOW command
|
|
|
|
*/
|
2004-10-22 21:48:19 +02:00
|
|
|
static void
|
2003-05-06 22:26:28 +02:00
|
|
|
ShowGUCConfigOption(const char *name, DestReceiver *dest)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
2002-07-20 07:49:28 +02:00
|
|
|
TupOutputState *tstate;
|
2002-09-04 22:31:48 +02:00
|
|
|
TupleDesc tupdesc;
|
|
|
|
const char *varname;
|
|
|
|
char *value;
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2002-07-20 17:12:56 +02:00
|
|
|
/* Get the value and canonical spelling of name */
|
|
|
|
value = GetConfigOptionByName(name, &varname);
|
|
|
|
|
2002-07-20 07:49:28 +02:00
|
|
|
/* need a tuple descriptor representing a single TEXT column */
|
2002-09-02 03:05:06 +02:00
|
|
|
tupdesc = CreateTemplateTupleDesc(1, false);
|
2003-08-12 01:04:50 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2002-07-20 07:49:28 +02:00
|
|
|
/* prepare for projection of tuples */
|
|
|
|
tstate = begin_tup_output_tupdesc(dest, tupdesc);
|
|
|
|
|
|
|
|
/* Send it */
|
2002-08-29 02:17:06 +02:00
|
|
|
do_text_output_oneline(tstate, value);
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
end_tup_output(tstate);
|
2001-06-07 06:50:57 +02:00
|
|
|
}
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
|
|
|
* SHOW ALL command
|
|
|
|
*/
|
2004-10-22 21:48:19 +02:00
|
|
|
static void
|
2003-05-06 22:26:28 +02:00
|
|
|
ShowAllGUCConfig(DestReceiver *dest)
|
2001-06-07 06:50:57 +02:00
|
|
|
{
|
2004-10-22 21:48:19 +02:00
|
|
|
bool am_superuser = superuser();
|
2001-06-07 06:50:57 +02:00
|
|
|
int i;
|
2002-07-20 07:49:28 +02:00
|
|
|
TupOutputState *tstate;
|
2002-09-04 22:31:48 +02:00
|
|
|
TupleDesc tupdesc;
|
2005-06-14 22:42:53 +02:00
|
|
|
char *values[3];
|
2002-07-20 07:49:28 +02:00
|
|
|
|
2005-06-14 22:42:53 +02:00
|
|
|
/* need a tuple descriptor representing three TEXT columns */
|
|
|
|
tupdesc = CreateTemplateTupleDesc(3, false);
|
2002-07-20 07:49:28 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2002-07-20 07:49:28 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2005-06-14 22:42:53 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
|
|
|
|
TEXTOID, -1, 0);
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
/* prepare for projection of tuples */
|
|
|
|
tstate = begin_tup_output_tupdesc(dest, tupdesc);
|
2001-06-07 06:50:57 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
for (i = 0; i < num_guc_variables; i++)
|
|
|
|
{
|
2002-07-20 17:12:56 +02:00
|
|
|
struct config_generic *conf = guc_variables[i];
|
|
|
|
|
2004-10-22 21:48:19 +02:00
|
|
|
if ((conf->flags & GUC_NO_SHOW_ALL) ||
|
|
|
|
((conf->flags & GUC_SUPERUSER_ONLY) && !am_superuser))
|
2002-07-20 17:12:56 +02:00
|
|
|
continue;
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
/* assign to the values array */
|
2002-07-20 17:12:56 +02:00
|
|
|
values[0] = (char *) conf->name;
|
2006-07-27 10:30:41 +02:00
|
|
|
values[1] = _ShowOption(conf, true);
|
2005-06-14 22:42:53 +02:00
|
|
|
values[2] = (char *) conf->short_desc;
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
/* send it to dest */
|
|
|
|
do_tup_output(tstate, values);
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2006-08-14 04:27:27 +02:00
|
|
|
/* clean up */
|
2002-07-20 17:12:56 +02:00
|
|
|
if (values[1] != NULL)
|
|
|
|
pfree(values[1]);
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
end_tup_output(tstate);
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2001-06-07 06:50:57 +02:00
|
|
|
|
2002-07-20 07:49:28 +02:00
|
|
|
/*
|
2002-07-20 17:12:56 +02:00
|
|
|
* Return GUC variable value by name; optionally return canonical
|
|
|
|
* form of name. Return value is palloc'd.
|
2002-07-20 07:49:28 +02:00
|
|
|
*/
|
|
|
|
char *
|
2002-07-20 17:12:56 +02:00
|
|
|
GetConfigOptionByName(const char *name, const char **varname)
|
2002-07-20 07:49:28 +02:00
|
|
|
{
|
|
|
|
struct config_generic *record;
|
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
record = find_option(name, false, ERROR);
|
2002-07-20 07:49:28 +02:00
|
|
|
if (record == NULL)
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
2005-10-15 04:49:52 +02:00
|
|
|
errmsg("unrecognized configuration parameter \"%s\"", name)));
|
2004-10-22 21:48:19 +02:00
|
|
|
if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("must be superuser to examine \"%s\"", name)));
|
2002-07-20 07:49:28 +02:00
|
|
|
|
2002-07-20 17:12:56 +02:00
|
|
|
if (varname)
|
|
|
|
*varname = record->name;
|
|
|
|
|
2006-07-27 10:30:41 +02:00
|
|
|
return _ShowOption(record, true);
|
2002-07-20 07:49:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2002-07-20 17:12:56 +02:00
|
|
|
* Return GUC variable value by variable number; optionally return canonical
|
|
|
|
* form of name. Return value is palloc'd.
|
2002-07-20 07:49:28 +02:00
|
|
|
*/
|
2003-07-27 06:35:54 +02:00
|
|
|
void
|
|
|
|
GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
|
2002-07-20 07:49:28 +02:00
|
|
|
{
|
2003-08-04 02:43:34 +02:00
|
|
|
char buffer[256];
|
|
|
|
struct config_generic *conf;
|
2002-07-30 18:20:03 +02:00
|
|
|
|
|
|
|
/* check requested variable number valid */
|
|
|
|
Assert((varnum >= 0) && (varnum < num_guc_variables));
|
|
|
|
|
|
|
|
conf = guc_variables[varnum];
|
2002-07-20 07:49:28 +02:00
|
|
|
|
2002-07-30 18:20:03 +02:00
|
|
|
if (noshow)
|
2004-10-22 21:48:19 +02:00
|
|
|
{
|
|
|
|
if ((conf->flags & GUC_NO_SHOW_ALL) ||
|
|
|
|
((conf->flags & GUC_SUPERUSER_ONLY) && !superuser()))
|
|
|
|
*noshow = true;
|
|
|
|
else
|
|
|
|
*noshow = false;
|
|
|
|
}
|
2002-07-30 18:20:03 +02:00
|
|
|
|
2003-07-27 06:35:54 +02:00
|
|
|
/* first get the generic attributes */
|
|
|
|
|
|
|
|
/* name */
|
|
|
|
values[0] = conf->name;
|
|
|
|
|
|
|
|
/* setting : use _ShowOption in order to avoid duplicating the logic */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[1] = _ShowOption(conf, false);
|
|
|
|
|
|
|
|
/* unit */
|
|
|
|
if (conf->vartype == PGC_INT)
|
|
|
|
{
|
2006-10-03 23:11:55 +02:00
|
|
|
static char buf[8];
|
2006-07-27 10:30:41 +02:00
|
|
|
|
2006-10-03 23:11:55 +02:00
|
|
|
switch (conf->flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME))
|
|
|
|
{
|
|
|
|
case GUC_UNIT_KB:
|
|
|
|
values[2] = "kB";
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_BLOCKS:
|
2006-10-04 02:30:14 +02:00
|
|
|
snprintf(buf, sizeof(buf), "%dkB", BLCKSZ / 1024);
|
2006-10-03 23:11:55 +02:00
|
|
|
values[2] = buf;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_XBLOCKS:
|
2006-10-04 02:30:14 +02:00
|
|
|
snprintf(buf, sizeof(buf), "%dkB", XLOG_BLCKSZ / 1024);
|
2006-10-03 23:11:55 +02:00
|
|
|
values[2] = buf;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_MS:
|
|
|
|
values[2] = "ms";
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_S:
|
|
|
|
values[2] = "s";
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_MIN:
|
|
|
|
values[2] = "min";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
values[2] = "";
|
|
|
|
break;
|
2006-07-27 10:30:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
values[2] = NULL;
|
2003-07-27 06:35:54 +02:00
|
|
|
|
2003-12-03 19:52:00 +01:00
|
|
|
/* group */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[3] = config_group_names[conf->group];
|
2003-12-03 19:52:00 +01:00
|
|
|
|
|
|
|
/* short_desc */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[4] = conf->short_desc;
|
2003-12-03 19:52:00 +01:00
|
|
|
|
|
|
|
/* extra_desc */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[5] = conf->long_desc;
|
2003-12-03 19:52:00 +01:00
|
|
|
|
2003-07-27 06:35:54 +02:00
|
|
|
/* context */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[6] = GucContext_Names[conf->context];
|
2003-07-27 06:35:54 +02:00
|
|
|
|
|
|
|
/* vartype */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[7] = config_type_names[conf->vartype];
|
2003-07-27 06:35:54 +02:00
|
|
|
|
|
|
|
/* source */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[8] = GucSource_Names[conf->source];
|
2003-07-27 06:35:54 +02:00
|
|
|
|
|
|
|
/* now get the type specifc attributes */
|
|
|
|
switch (conf->vartype)
|
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
|
|
|
{
|
|
|
|
/* min_val */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[9] = NULL;
|
2003-07-27 06:35:54 +02:00
|
|
|
|
|
|
|
/* max_val */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[10] = NULL;
|
2008-03-10 13:55:13 +01:00
|
|
|
|
|
|
|
/* enumvals */
|
|
|
|
values[11] = NULL;
|
2003-07-27 06:35:54 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PGC_INT:
|
|
|
|
{
|
|
|
|
struct config_int *lconf = (struct config_int *) conf;
|
|
|
|
|
|
|
|
/* min_val */
|
|
|
|
snprintf(buffer, sizeof(buffer), "%d", lconf->min);
|
2006-07-27 10:30:41 +02:00
|
|
|
values[9] = pstrdup(buffer);
|
2003-07-27 06:35:54 +02:00
|
|
|
|
|
|
|
/* max_val */
|
|
|
|
snprintf(buffer, sizeof(buffer), "%d", lconf->max);
|
2006-07-27 10:30:41 +02:00
|
|
|
values[10] = pstrdup(buffer);
|
2008-03-10 13:55:13 +01:00
|
|
|
|
|
|
|
/* enumvals */
|
|
|
|
values[11] = NULL;
|
2003-07-27 06:35:54 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PGC_REAL:
|
|
|
|
{
|
|
|
|
struct config_real *lconf = (struct config_real *) conf;
|
|
|
|
|
|
|
|
/* min_val */
|
|
|
|
snprintf(buffer, sizeof(buffer), "%g", lconf->min);
|
2006-07-27 10:30:41 +02:00
|
|
|
values[9] = pstrdup(buffer);
|
2003-07-27 06:35:54 +02:00
|
|
|
|
|
|
|
/* max_val */
|
|
|
|
snprintf(buffer, sizeof(buffer), "%g", lconf->max);
|
2006-07-27 10:30:41 +02:00
|
|
|
values[10] = pstrdup(buffer);
|
2008-03-10 13:55:13 +01:00
|
|
|
|
|
|
|
/* enumvals */
|
|
|
|
values[11] = NULL;
|
2003-07-27 06:35:54 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PGC_STRING:
|
|
|
|
{
|
|
|
|
/* min_val */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[9] = NULL;
|
2003-07-27 06:35:54 +02:00
|
|
|
|
|
|
|
/* max_val */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[10] = NULL;
|
2008-03-10 13:55:13 +01:00
|
|
|
|
|
|
|
/* enumvals */
|
|
|
|
values[11] = NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PGC_ENUM:
|
|
|
|
{
|
|
|
|
/* min_val */
|
|
|
|
values[9] = NULL;
|
|
|
|
|
|
|
|
/* max_val */
|
|
|
|
values[10] = NULL;
|
|
|
|
|
|
|
|
/* enumvals */
|
|
|
|
values[11] = config_enum_get_options((struct config_enum *) conf, "", "");
|
2003-07-27 06:35:54 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* should never get here, but in case we do, set 'em to NULL
|
2003-07-27 06:35:54 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* min_val */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[9] = NULL;
|
2003-07-27 06:35:54 +02:00
|
|
|
|
|
|
|
/* max_val */
|
2006-07-27 10:30:41 +02:00
|
|
|
values[10] = NULL;
|
2008-03-10 13:55:13 +01:00
|
|
|
|
|
|
|
/* enumvals */
|
|
|
|
values[11] = NULL;
|
2003-07-27 06:35:54 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2002-07-20 07:49:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return the total number of GUC variables
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
GetNumConfigOptions(void)
|
|
|
|
{
|
|
|
|
return num_guc_variables;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* show_config_by_name - equiv to SHOW X command but implemented as
|
|
|
|
* a function.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
show_config_by_name(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
char *varname;
|
|
|
|
char *varval;
|
|
|
|
text *result_text;
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
/* Get the GUC variable name */
|
2002-07-20 17:12:56 +02:00
|
|
|
varname = DatumGetCString(DirectFunctionCall1(textout, PG_GETARG_DATUM(0)));
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
/* Get the value */
|
2002-07-20 17:12:56 +02:00
|
|
|
varval = GetConfigOptionByName(varname, NULL);
|
2002-07-20 07:49:28 +02:00
|
|
|
|
|
|
|
/* Convert to text */
|
|
|
|
result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(varval)));
|
|
|
|
|
|
|
|
/* return it */
|
|
|
|
PG_RETURN_TEXT_P(result_text);
|
|
|
|
}
|
|
|
|
|
2002-08-15 04:51:27 +02:00
|
|
|
/*
|
|
|
|
* show_all_settings - equiv to SHOW ALL command but implemented as
|
|
|
|
* a Table Function.
|
|
|
|
*/
|
2008-03-10 13:55:13 +01:00
|
|
|
#define NUM_PG_SETTINGS_ATTS 12
|
2003-07-27 06:35:54 +02:00
|
|
|
|
2002-08-15 04:51:27 +02:00
|
|
|
Datum
|
|
|
|
show_all_settings(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
FuncCallContext *funcctx;
|
|
|
|
TupleDesc tupdesc;
|
|
|
|
int call_cntr;
|
|
|
|
int max_calls;
|
|
|
|
AttInMetadata *attinmeta;
|
|
|
|
MemoryContext oldcontext;
|
2002-08-15 04:51:27 +02:00
|
|
|
|
|
|
|
/* stuff done only on the first call of the function */
|
2002-09-04 22:31:48 +02:00
|
|
|
if (SRF_IS_FIRSTCALL())
|
|
|
|
{
|
2002-08-15 04:51:27 +02:00
|
|
|
/* create a function context for cross-call persistence */
|
2002-09-04 22:31:48 +02:00
|
|
|
funcctx = SRF_FIRSTCALL_INIT();
|
2002-08-15 04:51:27 +02:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* switch to memory context appropriate for multiple function calls
|
2002-09-04 22:31:48 +02:00
|
|
|
*/
|
2002-08-29 19:14:33 +02:00
|
|
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
|
|
|
|
2003-07-27 06:35:54 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns
|
|
|
|
* of the appropriate types
|
2003-07-27 06:35:54 +02:00
|
|
|
*/
|
|
|
|
tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS, false);
|
2002-08-15 04:51:27 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2002-08-15 04:51:27 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2006-07-27 10:30:41 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "unit",
|
|
|
|
TEXTOID, -1, 0);
|
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "category",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2006-07-27 10:30:41 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "short_desc",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2006-07-27 10:30:41 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 6, "extra_desc",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2006-07-27 10:30:41 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 7, "context",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2006-07-27 10:30:41 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 8, "vartype",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2006-07-27 10:30:41 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 9, "source",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2006-07-27 10:30:41 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 10, "min_val",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2006-07-27 10:30:41 +02:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 11, "max_val",
|
2004-04-01 23:28:47 +02:00
|
|
|
TEXTOID, -1, 0);
|
2008-03-10 13:55:13 +01:00
|
|
|
TupleDescInitEntry(tupdesc, (AttrNumber) 12, "enumvals",
|
|
|
|
TEXTOID, -1, 0);
|
2002-08-15 04:51:27 +02:00
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Generate attribute metadata needed later to produce tuples from raw
|
|
|
|
* C strings
|
2002-08-15 04:51:27 +02:00
|
|
|
*/
|
|
|
|
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
|
|
|
funcctx->attinmeta = attinmeta;
|
|
|
|
|
|
|
|
/* total number of tuples to be returned */
|
|
|
|
funcctx->max_calls = GetNumConfigOptions();
|
2002-08-29 19:14:33 +02:00
|
|
|
|
|
|
|
MemoryContextSwitchTo(oldcontext);
|
2002-09-04 22:31:48 +02:00
|
|
|
}
|
2002-08-15 04:51:27 +02:00
|
|
|
|
|
|
|
/* stuff done on every call of the function */
|
2002-09-04 22:31:48 +02:00
|
|
|
funcctx = SRF_PERCALL_SETUP();
|
2002-08-15 04:51:27 +02:00
|
|
|
|
|
|
|
call_cntr = funcctx->call_cntr;
|
|
|
|
max_calls = funcctx->max_calls;
|
|
|
|
attinmeta = funcctx->attinmeta;
|
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
if (call_cntr < max_calls) /* do when there is more left to send */
|
|
|
|
{
|
2003-07-27 06:35:54 +02:00
|
|
|
char *values[NUM_PG_SETTINGS_ATTS];
|
2002-08-15 04:51:27 +02:00
|
|
|
bool noshow;
|
|
|
|
HeapTuple tuple;
|
|
|
|
Datum result;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the next visible GUC variable name and value
|
|
|
|
*/
|
|
|
|
do
|
|
|
|
{
|
2003-07-27 06:35:54 +02:00
|
|
|
GetConfigOptionByNum(call_cntr, (const char **) values, &noshow);
|
2002-08-15 04:51:27 +02:00
|
|
|
if (noshow)
|
|
|
|
{
|
|
|
|
/* bump the counter and get the next config setting */
|
|
|
|
call_cntr = ++funcctx->call_cntr;
|
|
|
|
|
|
|
|
/* make sure we haven't gone too far now */
|
|
|
|
if (call_cntr >= max_calls)
|
2002-09-04 22:31:48 +02:00
|
|
|
SRF_RETURN_DONE(funcctx);
|
2002-08-15 04:51:27 +02:00
|
|
|
}
|
|
|
|
} while (noshow);
|
|
|
|
|
|
|
|
/* build a tuple */
|
|
|
|
tuple = BuildTupleFromCStrings(attinmeta, values);
|
|
|
|
|
|
|
|
/* make the tuple into a datum */
|
2004-04-01 23:28:47 +02:00
|
|
|
result = HeapTupleGetDatum(tuple);
|
2002-08-15 04:51:27 +02:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
SRF_RETURN_NEXT(funcctx, result);
|
|
|
|
}
|
|
|
|
else
|
2003-04-25 21:45:10 +02:00
|
|
|
{
|
|
|
|
/* do when there is no more left */
|
2002-09-04 22:31:48 +02:00
|
|
|
SRF_RETURN_DONE(funcctx);
|
2003-04-25 21:45:10 +02:00
|
|
|
}
|
2002-08-15 04:51:27 +02:00
|
|
|
}
|
|
|
|
|
2002-07-20 07:49:28 +02:00
|
|
|
static char *
|
2006-07-27 10:30:41 +02:00
|
|
|
_ShowOption(struct config_generic * record, bool use_units)
|
2002-05-17 03:19:19 +02:00
|
|
|
{
|
|
|
|
char buffer[256];
|
|
|
|
const char *val;
|
2001-06-07 06:50:57 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
switch (record->vartype)
|
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
|
|
|
{
|
|
|
|
struct config_bool *conf = (struct config_bool *) record;
|
2001-06-07 06:50:57 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
if (conf->show_hook)
|
|
|
|
val = (*conf->show_hook) ();
|
|
|
|
else
|
|
|
|
val = *conf->variable ? "on" : "off";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PGC_INT:
|
|
|
|
{
|
|
|
|
struct config_int *conf = (struct config_int *) record;
|
|
|
|
|
|
|
|
if (conf->show_hook)
|
|
|
|
val = (*conf->show_hook) ();
|
|
|
|
else
|
|
|
|
{
|
2006-10-04 02:30:14 +02:00
|
|
|
char unit[4];
|
|
|
|
int result = *conf->variable;
|
2006-07-27 10:30:41 +02:00
|
|
|
|
|
|
|
if (use_units && result > 0 && (record->flags & GUC_UNIT_MEMORY))
|
|
|
|
{
|
2006-10-03 23:11:55 +02:00
|
|
|
switch (record->flags & GUC_UNIT_MEMORY)
|
|
|
|
{
|
|
|
|
case GUC_UNIT_BLOCKS:
|
2006-10-04 02:30:14 +02:00
|
|
|
result *= BLCKSZ / 1024;
|
2006-10-03 23:11:55 +02:00
|
|
|
break;
|
|
|
|
case GUC_UNIT_XBLOCKS:
|
2006-10-04 02:30:14 +02:00
|
|
|
result *= XLOG_BLCKSZ / 1024;
|
2006-10-03 23:11:55 +02:00
|
|
|
break;
|
|
|
|
}
|
2006-07-27 10:30:41 +02:00
|
|
|
|
|
|
|
if (result % KB_PER_GB == 0)
|
|
|
|
{
|
|
|
|
result /= KB_PER_GB;
|
|
|
|
strcpy(unit, "GB");
|
|
|
|
}
|
|
|
|
else if (result % KB_PER_MB == 0)
|
|
|
|
{
|
|
|
|
result /= KB_PER_MB;
|
|
|
|
strcpy(unit, "MB");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strcpy(unit, "kB");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (use_units && result > 0 && (record->flags & GUC_UNIT_TIME))
|
|
|
|
{
|
2006-10-03 23:11:55 +02:00
|
|
|
switch (record->flags & GUC_UNIT_TIME)
|
|
|
|
{
|
|
|
|
case GUC_UNIT_S:
|
|
|
|
result *= MS_PER_S;
|
|
|
|
break;
|
|
|
|
case GUC_UNIT_MIN:
|
|
|
|
result *= MS_PER_MIN;
|
|
|
|
break;
|
|
|
|
}
|
2006-07-27 10:30:41 +02:00
|
|
|
|
|
|
|
if (result % MS_PER_D == 0)
|
|
|
|
{
|
|
|
|
result /= MS_PER_D;
|
|
|
|
strcpy(unit, "d");
|
|
|
|
}
|
|
|
|
else if (result % MS_PER_H == 0)
|
|
|
|
{
|
|
|
|
result /= MS_PER_H;
|
|
|
|
strcpy(unit, "h");
|
|
|
|
}
|
|
|
|
else if (result % MS_PER_MIN == 0)
|
|
|
|
{
|
|
|
|
result /= MS_PER_MIN;
|
|
|
|
strcpy(unit, "min");
|
|
|
|
}
|
|
|
|
else if (result % MS_PER_S == 0)
|
|
|
|
{
|
|
|
|
result /= MS_PER_S;
|
|
|
|
strcpy(unit, "s");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strcpy(unit, "ms");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
strcpy(unit, "");
|
|
|
|
|
|
|
|
snprintf(buffer, sizeof(buffer), "%d%s",
|
2006-10-04 02:30:14 +02:00
|
|
|
(int) result, unit);
|
2002-05-17 03:19:19 +02:00
|
|
|
val = buffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PGC_REAL:
|
|
|
|
{
|
|
|
|
struct config_real *conf = (struct config_real *) record;
|
|
|
|
|
|
|
|
if (conf->show_hook)
|
|
|
|
val = (*conf->show_hook) ();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
snprintf(buffer, sizeof(buffer), "%g",
|
|
|
|
*conf->variable);
|
|
|
|
val = buffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PGC_STRING:
|
|
|
|
{
|
|
|
|
struct config_string *conf = (struct config_string *) record;
|
2001-06-07 06:50:57 +02:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
if (conf->show_hook)
|
|
|
|
val = (*conf->show_hook) ();
|
|
|
|
else if (*conf->variable && **conf->variable)
|
|
|
|
val = *conf->variable;
|
|
|
|
else
|
2006-07-26 13:39:47 +02:00
|
|
|
val = "";
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
|
|
|
break;
|
2001-06-07 06:50:57 +02:00
|
|
|
|
2008-03-10 13:55:13 +01:00
|
|
|
case PGC_ENUM:
|
|
|
|
{
|
|
|
|
struct config_enum *conf = (struct config_enum *) record;
|
|
|
|
|
|
|
|
if(conf->show_hook)
|
|
|
|
val = (*conf->show_hook) ();
|
|
|
|
else
|
|
|
|
val = config_enum_lookup_value(conf, *conf->variable);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
default:
|
|
|
|
/* just to keep compiler quiet */
|
|
|
|
val = "???";
|
|
|
|
break;
|
|
|
|
}
|
2001-06-07 06:50:57 +02:00
|
|
|
|
2002-07-20 07:49:28 +02:00
|
|
|
return pstrdup(val);
|
2002-05-17 03:19:19 +02:00
|
|
|
}
|
2000-07-03 22:46:10 +02:00
|
|
|
|
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
/*
|
|
|
|
* Attempt (badly) to detect if a proposed new GUC setting is the same
|
|
|
|
* as the current value.
|
|
|
|
*
|
|
|
|
* XXX this does not really work because it doesn't account for the
|
|
|
|
* effects of canonicalization of string values by assign_hooks.
|
|
|
|
*/
|
2006-02-04 13:50:47 +01:00
|
|
|
static bool
|
2007-11-15 22:14:46 +01:00
|
|
|
is_newvalue_equal(struct config_generic * record, const char *newvalue)
|
2006-02-04 13:50:47 +01:00
|
|
|
{
|
2007-09-10 02:57:22 +02:00
|
|
|
/* newvalue == NULL isn't supported */
|
|
|
|
Assert(newvalue != NULL);
|
|
|
|
|
2006-02-04 13:50:47 +01:00
|
|
|
switch (record->vartype)
|
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
2006-10-04 02:30:14 +02:00
|
|
|
{
|
|
|
|
struct config_bool *conf = (struct config_bool *) record;
|
|
|
|
bool newval;
|
2006-02-04 13:50:47 +01:00
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
return parse_bool(newvalue, &newval)
|
|
|
|
&& *conf->variable == newval;
|
2006-10-04 02:30:14 +02:00
|
|
|
}
|
2006-02-04 13:50:47 +01:00
|
|
|
case PGC_INT:
|
2006-10-04 02:30:14 +02:00
|
|
|
{
|
|
|
|
struct config_int *conf = (struct config_int *) record;
|
|
|
|
int newval;
|
2006-02-04 13:50:47 +01:00
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
return parse_int(newvalue, &newval, record->flags, NULL)
|
|
|
|
&& *conf->variable == newval;
|
2006-10-04 02:30:14 +02:00
|
|
|
}
|
2006-02-04 13:50:47 +01:00
|
|
|
case PGC_REAL:
|
2006-10-04 02:30:14 +02:00
|
|
|
{
|
|
|
|
struct config_real *conf = (struct config_real *) record;
|
|
|
|
double newval;
|
2006-02-04 13:50:47 +01:00
|
|
|
|
2007-06-21 20:14:21 +02:00
|
|
|
return parse_real(newvalue, &newval)
|
|
|
|
&& *conf->variable == newval;
|
2006-10-04 02:30:14 +02:00
|
|
|
}
|
2006-02-04 13:50:47 +01:00
|
|
|
case PGC_STRING:
|
2006-10-04 02:30:14 +02:00
|
|
|
{
|
|
|
|
struct config_string *conf = (struct config_string *) record;
|
2006-02-04 13:50:47 +01:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
return *conf->variable != NULL &&
|
|
|
|
strcmp(*conf->variable, newvalue) == 0;
|
2006-10-04 02:30:14 +02:00
|
|
|
}
|
2008-03-10 13:55:13 +01:00
|
|
|
|
|
|
|
case PGC_ENUM:
|
|
|
|
{
|
|
|
|
struct config_enum *conf = (struct config_enum *) record;
|
|
|
|
int newval;
|
|
|
|
|
|
|
|
return config_enum_lookup_name(conf, newvalue, &newval)
|
|
|
|
&& *conf->variable == newval;
|
|
|
|
}
|
2006-02-04 13:50:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-05-03 00:02:47 +02:00
|
|
|
#ifdef EXEC_BACKEND
|
2005-07-04 06:51:52 +02:00
|
|
|
|
2003-05-03 00:02:47 +02:00
|
|
|
/*
|
|
|
|
* This routine dumps out all non-default GUC options into a binary
|
|
|
|
* file that is read by all exec'ed backends. The format is:
|
|
|
|
*
|
|
|
|
* variable name, string, null terminated
|
|
|
|
* variable value, string, null terminated
|
|
|
|
* variable source, integer
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
write_nondefault_variables(GucContext context)
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
int i;
|
|
|
|
int elevel;
|
|
|
|
FILE *fp;
|
2003-05-03 00:02:47 +02:00
|
|
|
|
|
|
|
Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
|
2004-09-01 00:43:58 +02:00
|
|
|
|
|
|
|
elevel = (context == PGC_SIGHUP) ? LOG : ERROR;
|
2003-05-03 00:02:47 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Open file
|
|
|
|
*/
|
2005-07-04 06:51:52 +02:00
|
|
|
fp = AllocateFile(CONFIG_EXEC_PARAMS_NEW, "w");
|
2003-07-04 18:41:22 +02:00
|
|
|
if (!fp)
|
|
|
|
{
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(elevel,
|
|
|
|
(errcode_for_file_access(),
|
2005-07-04 06:51:52 +02:00
|
|
|
errmsg("could not write to file \"%s\": %m",
|
|
|
|
CONFIG_EXEC_PARAMS_NEW)));
|
2003-05-03 00:02:47 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < num_guc_variables; i++)
|
|
|
|
{
|
|
|
|
struct config_generic *gconf = guc_variables[i];
|
|
|
|
|
|
|
|
if (gconf->source != PGC_S_DEFAULT)
|
|
|
|
{
|
|
|
|
fprintf(fp, "%s", gconf->name);
|
|
|
|
fputc(0, fp);
|
|
|
|
|
|
|
|
switch (gconf->vartype)
|
|
|
|
{
|
|
|
|
case PGC_BOOL:
|
|
|
|
{
|
|
|
|
struct config_bool *conf = (struct config_bool *) gconf;
|
|
|
|
|
|
|
|
if (*conf->variable == 0)
|
|
|
|
fprintf(fp, "false");
|
|
|
|
else
|
|
|
|
fprintf(fp, "true");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PGC_INT:
|
|
|
|
{
|
|
|
|
struct config_int *conf = (struct config_int *) gconf;
|
|
|
|
|
|
|
|
fprintf(fp, "%d", *conf->variable);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PGC_REAL:
|
|
|
|
{
|
|
|
|
struct config_real *conf = (struct config_real *) gconf;
|
|
|
|
|
|
|
|
/* Could lose precision here? */
|
|
|
|
fprintf(fp, "%f", *conf->variable);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PGC_STRING:
|
|
|
|
{
|
|
|
|
struct config_string *conf = (struct config_string *) gconf;
|
|
|
|
|
|
|
|
fprintf(fp, "%s", *conf->variable);
|
|
|
|
}
|
|
|
|
break;
|
2008-03-10 13:55:13 +01:00
|
|
|
|
|
|
|
case PGC_ENUM:
|
|
|
|
{
|
|
|
|
struct config_enum *conf = (struct config_enum *) gconf;
|
|
|
|
|
|
|
|
fprintf(fp, "%s", config_enum_lookup_value(conf, *conf->variable));
|
|
|
|
}
|
|
|
|
break;
|
2003-05-03 00:02:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fputc(0, fp);
|
|
|
|
|
|
|
|
fwrite(&gconf->source, sizeof(gconf->source), 1, fp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-01-26 23:35:32 +01:00
|
|
|
if (FreeFile(fp))
|
|
|
|
{
|
|
|
|
ereport(elevel,
|
|
|
|
(errcode_for_file_access(),
|
2005-07-04 06:51:52 +02:00
|
|
|
errmsg("could not write to file \"%s\": %m",
|
|
|
|
CONFIG_EXEC_PARAMS_NEW)));
|
2004-01-26 23:35:32 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-02-02 01:17:23 +01:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Put new file in place. This could delay on Win32, but we don't hold
|
|
|
|
* any exclusive locks.
|
2004-02-02 01:17:23 +01:00
|
|
|
*/
|
2005-07-04 06:51:52 +02:00
|
|
|
rename(CONFIG_EXEC_PARAMS_NEW, CONFIG_EXEC_PARAMS);
|
2003-05-03 00:02:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read string, including null byte from file
|
|
|
|
*
|
|
|
|
* Return NULL on EOF and nothing read
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
read_string_with_null(FILE *fp)
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
int i = 0,
|
|
|
|
ch,
|
|
|
|
maxlen = 256;
|
|
|
|
char *str = NULL;
|
2003-05-03 00:02:47 +02:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ((ch = fgetc(fp)) == EOF)
|
|
|
|
{
|
|
|
|
if (i == 0)
|
|
|
|
return NULL;
|
|
|
|
else
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(FATAL, "invalid format of exec config params file");
|
2003-05-03 00:02:47 +02:00
|
|
|
}
|
|
|
|
if (i == 0)
|
2004-07-06 01:14:14 +02:00
|
|
|
str = guc_malloc(FATAL, maxlen);
|
2003-05-03 00:02:47 +02:00
|
|
|
else if (i == maxlen)
|
2004-07-06 01:14:14 +02:00
|
|
|
str = guc_realloc(FATAL, str, maxlen *= 2);
|
2003-05-03 00:02:47 +02:00
|
|
|
str[i++] = ch;
|
|
|
|
} while (ch != 0);
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This routine loads a previous postmaster dump of its non-default
|
|
|
|
* settings.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
read_nondefault_variables(void)
|
|
|
|
{
|
2003-07-04 18:41:22 +02:00
|
|
|
FILE *fp;
|
|
|
|
char *varname,
|
|
|
|
*varvalue;
|
|
|
|
int varsource;
|
2003-05-03 00:02:47 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Open file
|
|
|
|
*/
|
2005-07-04 06:51:52 +02:00
|
|
|
fp = AllocateFile(CONFIG_EXEC_PARAMS, "r");
|
2003-07-04 18:41:22 +02:00
|
|
|
if (!fp)
|
|
|
|
{
|
|
|
|
/* File not found is fine */
|
|
|
|
if (errno != ENOENT)
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(FATAL,
|
|
|
|
(errcode_for_file_access(),
|
2005-07-04 06:51:52 +02:00
|
|
|
errmsg("could not read from file \"%s\": %m",
|
|
|
|
CONFIG_EXEC_PARAMS)));
|
2003-05-03 00:02:47 +02:00
|
|
|
return;
|
2003-07-04 18:41:22 +02:00
|
|
|
}
|
2003-05-03 00:02:47 +02:00
|
|
|
|
2003-07-25 22:18:01 +02:00
|
|
|
for (;;)
|
2003-05-03 00:02:47 +02:00
|
|
|
{
|
2004-06-11 05:54:54 +02:00
|
|
|
struct config_generic *record;
|
|
|
|
|
2003-05-03 00:02:47 +02:00
|
|
|
if ((varname = read_string_with_null(fp)) == NULL)
|
|
|
|
break;
|
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
if ((record = find_option(varname, true, FATAL)) == NULL)
|
2004-08-29 07:07:03 +02:00
|
|
|
elog(FATAL, "failed to locate variable %s in exec config params file", varname);
|
2003-05-03 00:02:47 +02:00
|
|
|
if ((varvalue = read_string_with_null(fp)) == NULL)
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(FATAL, "invalid format of exec config params file");
|
2003-07-04 18:41:22 +02:00
|
|
|
if (fread(&varsource, sizeof(varsource), 1, fp) == 0)
|
2003-07-25 22:18:01 +02:00
|
|
|
elog(FATAL, "invalid format of exec config params file");
|
2003-05-03 00:02:47 +02:00
|
|
|
|
2004-06-11 05:54:54 +02:00
|
|
|
(void) set_config_option(varname, varvalue, record->context,
|
2007-09-11 02:06:42 +02:00
|
|
|
varsource, GUC_ACTION_SET, true);
|
2003-05-03 00:02:47 +02:00
|
|
|
free(varname);
|
|
|
|
free(varvalue);
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeFile(fp);
|
|
|
|
}
|
2005-10-15 04:49:52 +02:00
|
|
|
#endif /* EXEC_BACKEND */
|
2003-05-03 00:02:47 +02:00
|
|
|
|
|
|
|
|
2000-07-03 22:46:10 +02:00
|
|
|
/*
|
|
|
|
* A little "long argument" simulation, although not quite GNU
|
|
|
|
* compliant. Takes a string of the form "some-option=some value" and
|
|
|
|
* returns name = "some_option" and value = "some value" in malloc'ed
|
|
|
|
* storage. Note that '-' is converted to '_' in the option name. If
|
|
|
|
* there is no '=' in the input string then value will be NULL.
|
|
|
|
*/
|
|
|
|
void
|
2001-03-22 05:01:46 +01:00
|
|
|
ParseLongOption(const char *string, char **name, char **value)
|
2000-07-03 22:46:10 +02:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
size_t equal_pos;
|
|
|
|
char *cp;
|
2000-07-03 22:46:10 +02:00
|
|
|
|
|
|
|
AssertArg(string);
|
|
|
|
AssertArg(name);
|
|
|
|
AssertArg(value);
|
|
|
|
|
|
|
|
equal_pos = strcspn(string, "=");
|
|
|
|
|
|
|
|
if (string[equal_pos] == '=')
|
|
|
|
{
|
2004-07-06 01:14:14 +02:00
|
|
|
*name = guc_malloc(FATAL, equal_pos + 1);
|
2007-02-07 01:52:35 +01:00
|
|
|
strlcpy(*name, string, equal_pos + 1);
|
2000-07-03 22:46:10 +02:00
|
|
|
|
2004-07-06 01:14:14 +02:00
|
|
|
*value = guc_strdup(FATAL, &string[equal_pos + 1]);
|
2000-07-03 22:46:10 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
else
|
2000-07-03 22:46:10 +02:00
|
|
|
{
|
2001-06-13 00:54:06 +02:00
|
|
|
/* no equal sign in string */
|
2004-07-06 01:14:14 +02:00
|
|
|
*name = guc_strdup(FATAL, string);
|
2000-07-03 22:46:10 +02:00
|
|
|
*value = NULL;
|
|
|
|
}
|
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
for (cp = *name; *cp; cp++)
|
2000-07-03 22:46:10 +02:00
|
|
|
if (*cp == '-')
|
|
|
|
*cp = '_';
|
|
|
|
}
|
2000-11-14 20:13:27 +01:00
|
|
|
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
/*
|
2007-09-03 02:39:26 +02:00
|
|
|
* Handle options fetched from pg_database.datconfig, pg_authid.rolconfig,
|
2007-11-15 22:14:46 +01:00
|
|
|
* pg_proc.proconfig, etc. Caller must specify proper context/source/action.
|
2007-09-03 02:39:26 +02:00
|
|
|
*
|
2002-12-02 06:20:47 +01:00
|
|
|
* The array parameter must be an array of TEXT (it must not be NULL).
|
2002-05-17 03:19:19 +02:00
|
|
|
*/
|
2002-03-01 23:45:19 +01:00
|
|
|
void
|
2007-09-03 02:39:26 +02:00
|
|
|
ProcessGUCArray(ArrayType *array,
|
2007-09-11 02:06:42 +02:00
|
|
|
GucContext context, GucSource source, GucAction action)
|
2002-03-01 23:45:19 +01:00
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
int i;
|
2002-03-01 23:45:19 +01:00
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
Assert(array != NULL);
|
2002-08-26 19:54:02 +02:00
|
|
|
Assert(ARR_ELEMTYPE(array) == TEXTOID);
|
|
|
|
Assert(ARR_NDIM(array) == 1);
|
|
|
|
Assert(ARR_LBOUND(array)[0] == 1);
|
2002-03-01 23:45:19 +01:00
|
|
|
|
|
|
|
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
|
|
|
{
|
|
|
|
Datum d;
|
|
|
|
bool isnull;
|
|
|
|
char *s;
|
|
|
|
char *name;
|
|
|
|
char *value;
|
|
|
|
|
|
|
|
d = array_ref(array, 1, &i,
|
2002-09-04 22:31:48 +02:00
|
|
|
-1 /* varlenarray */ ,
|
|
|
|
-1 /* TEXT's typlen */ ,
|
|
|
|
false /* TEXT's typbyval */ ,
|
|
|
|
'i' /* TEXT's typalign */ ,
|
2002-03-01 23:45:19 +01:00
|
|
|
&isnull);
|
|
|
|
|
|
|
|
if (isnull)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
s = DatumGetCString(DirectFunctionCall1(textout, d));
|
2002-05-17 22:32:29 +02:00
|
|
|
|
2002-03-01 23:45:19 +01:00
|
|
|
ParseLongOption(s, &name, &value);
|
|
|
|
if (!value)
|
|
|
|
{
|
2003-07-25 22:18:01 +02:00
|
|
|
ereport(WARNING,
|
|
|
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
2007-09-03 02:39:26 +02:00
|
|
|
errmsg("could not parse setting for parameter \"%s\"",
|
|
|
|
name)));
|
2002-05-17 22:32:29 +02:00
|
|
|
free(name);
|
2002-03-06 07:10:59 +01:00
|
|
|
continue;
|
2002-03-01 23:45:19 +01:00
|
|
|
}
|
|
|
|
|
2007-09-11 02:06:42 +02:00
|
|
|
(void) set_config_option(name, value, context, source, action, true);
|
2002-05-17 22:32:29 +02:00
|
|
|
|
|
|
|
free(name);
|
|
|
|
if (value)
|
|
|
|
free(value);
|
2002-03-01 23:45:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-02 06:20:47 +01:00
|
|
|
/*
|
|
|
|
* Add an entry to an option array. The array parameter may be NULL
|
|
|
|
* to indicate the current table entry is NULL.
|
|
|
|
*/
|
2002-03-01 23:45:19 +01:00
|
|
|
ArrayType *
|
|
|
|
GUCArrayAdd(ArrayType *array, const char *name, const char *value)
|
|
|
|
{
|
2003-01-28 19:04:02 +01:00
|
|
|
const char *varname;
|
2002-03-01 23:45:19 +01:00
|
|
|
Datum datum;
|
|
|
|
char *newval;
|
|
|
|
ArrayType *a;
|
|
|
|
|
|
|
|
Assert(name);
|
|
|
|
Assert(value);
|
|
|
|
|
|
|
|
/* test if the option is valid */
|
|
|
|
set_config_option(name, value,
|
|
|
|
superuser() ? PGC_SUSET : PGC_USERSET,
|
2007-09-11 02:06:42 +02:00
|
|
|
PGC_S_TEST, GUC_ACTION_SET, false);
|
2002-03-01 23:45:19 +01:00
|
|
|
|
2003-01-28 19:04:02 +01:00
|
|
|
/* convert name to canonical spelling, so we can use plain strcmp */
|
|
|
|
(void) GetConfigOptionByName(name, &varname);
|
|
|
|
name = varname;
|
|
|
|
|
2002-03-01 23:45:19 +01:00
|
|
|
newval = palloc(strlen(name) + 1 + strlen(value) + 1);
|
|
|
|
sprintf(newval, "%s=%s", name, value);
|
|
|
|
datum = DirectFunctionCall1(textin, CStringGetDatum(newval));
|
2002-03-06 07:10:59 +01:00
|
|
|
|
2002-03-01 23:45:19 +01:00
|
|
|
if (array)
|
|
|
|
{
|
2002-09-04 22:31:48 +02:00
|
|
|
int index;
|
|
|
|
bool isnull;
|
|
|
|
int i;
|
2002-03-01 23:45:19 +01:00
|
|
|
|
2002-08-26 19:54:02 +02:00
|
|
|
Assert(ARR_ELEMTYPE(array) == TEXTOID);
|
|
|
|
Assert(ARR_NDIM(array) == 1);
|
|
|
|
Assert(ARR_LBOUND(array)[0] == 1);
|
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
index = ARR_DIMS(array)[0] + 1; /* add after end */
|
2002-03-01 23:45:19 +01:00
|
|
|
|
|
|
|
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
|
|
|
{
|
|
|
|
Datum d;
|
|
|
|
char *current;
|
|
|
|
|
|
|
|
d = array_ref(array, 1, &i,
|
2002-09-04 22:31:48 +02:00
|
|
|
-1 /* varlenarray */ ,
|
|
|
|
-1 /* TEXT's typlen */ ,
|
|
|
|
false /* TEXT's typbyval */ ,
|
|
|
|
'i' /* TEXT's typalign */ ,
|
2002-03-01 23:45:19 +01:00
|
|
|
&isnull);
|
2002-08-26 19:54:02 +02:00
|
|
|
if (isnull)
|
|
|
|
continue;
|
2002-03-01 23:45:19 +01:00
|
|
|
current = DatumGetCString(DirectFunctionCall1(textout, d));
|
2002-09-04 22:31:48 +02:00
|
|
|
if (strncmp(current, newval, strlen(name) + 1) == 0)
|
2002-03-01 23:45:19 +01:00
|
|
|
{
|
|
|
|
index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-26 19:54:02 +02:00
|
|
|
a = array_set(array, 1, &index,
|
|
|
|
datum,
|
2005-11-17 23:14:56 +01:00
|
|
|
false,
|
|
|
|
-1 /* varlena array */ ,
|
2002-09-04 22:31:48 +02:00
|
|
|
-1 /* TEXT's typlen */ ,
|
|
|
|
false /* TEXT's typbyval */ ,
|
2005-11-17 23:14:56 +01:00
|
|
|
'i' /* TEXT's typalign */ );
|
2002-03-01 23:45:19 +01:00
|
|
|
}
|
|
|
|
else
|
2002-08-26 19:54:02 +02:00
|
|
|
a = construct_array(&datum, 1,
|
|
|
|
TEXTOID,
|
|
|
|
-1, false, 'i');
|
2002-03-01 23:45:19 +01:00
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-02 06:20:47 +01:00
|
|
|
/*
|
|
|
|
* Delete an entry from an option array. The array parameter may be NULL
|
|
|
|
* to indicate the current table entry is NULL. Also, if the return value
|
|
|
|
* is NULL then a null should be stored.
|
|
|
|
*/
|
2002-03-01 23:45:19 +01:00
|
|
|
ArrayType *
|
|
|
|
GUCArrayDelete(ArrayType *array, const char *name)
|
|
|
|
{
|
2003-01-28 19:04:02 +01:00
|
|
|
const char *varname;
|
2002-09-04 22:31:48 +02:00
|
|
|
ArrayType *newarray;
|
|
|
|
int i;
|
|
|
|
int index;
|
2002-03-01 23:45:19 +01:00
|
|
|
|
|
|
|
Assert(name);
|
|
|
|
|
|
|
|
/* test if the option is valid */
|
|
|
|
set_config_option(name, NULL,
|
|
|
|
superuser() ? PGC_SUSET : PGC_USERSET,
|
2007-09-11 02:06:42 +02:00
|
|
|
PGC_S_TEST, GUC_ACTION_SET, false);
|
2002-03-01 23:45:19 +01:00
|
|
|
|
2003-01-28 19:04:02 +01:00
|
|
|
/* convert name to canonical spelling, so we can use plain strcmp */
|
|
|
|
(void) GetConfigOptionByName(name, &varname);
|
|
|
|
name = varname;
|
|
|
|
|
2002-12-02 06:20:47 +01:00
|
|
|
/* if array is currently null, then surely nothing to delete */
|
|
|
|
if (!array)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
newarray = NULL;
|
2002-03-01 23:45:19 +01:00
|
|
|
index = 1;
|
|
|
|
|
|
|
|
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
|
|
|
{
|
|
|
|
Datum d;
|
|
|
|
char *val;
|
|
|
|
bool isnull;
|
|
|
|
|
|
|
|
d = array_ref(array, 1, &i,
|
2002-09-04 22:31:48 +02:00
|
|
|
-1 /* varlenarray */ ,
|
|
|
|
-1 /* TEXT's typlen */ ,
|
|
|
|
false /* TEXT's typbyval */ ,
|
|
|
|
'i' /* TEXT's typalign */ ,
|
2002-03-01 23:45:19 +01:00
|
|
|
&isnull);
|
2002-08-26 19:54:02 +02:00
|
|
|
if (isnull)
|
|
|
|
continue;
|
2002-03-01 23:45:19 +01:00
|
|
|
val = DatumGetCString(DirectFunctionCall1(textout, d));
|
|
|
|
|
2002-12-02 06:20:47 +01:00
|
|
|
/* ignore entry if it's what we want to delete */
|
2002-09-04 22:31:48 +02:00
|
|
|
if (strncmp(val, name, strlen(name)) == 0
|
2002-03-01 23:45:19 +01:00
|
|
|
&& val[strlen(name)] == '=')
|
|
|
|
continue;
|
|
|
|
|
2002-12-02 06:20:47 +01:00
|
|
|
/* else add it to the output array */
|
|
|
|
if (newarray)
|
|
|
|
{
|
|
|
|
newarray = array_set(newarray, 1, &index,
|
|
|
|
d,
|
2005-11-17 23:14:56 +01:00
|
|
|
false,
|
2002-12-02 06:20:47 +01:00
|
|
|
-1 /* varlenarray */ ,
|
|
|
|
-1 /* TEXT's typlen */ ,
|
|
|
|
false /* TEXT's typbyval */ ,
|
2005-11-17 23:14:56 +01:00
|
|
|
'i' /* TEXT's typalign */ );
|
2002-12-02 06:20:47 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
newarray = construct_array(&d, 1,
|
|
|
|
TEXTOID,
|
|
|
|
-1, false, 'i');
|
|
|
|
|
2002-03-01 23:45:19 +01:00
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return newarray;
|
|
|
|
}
|
2002-09-02 07:42:54 +02:00
|
|
|
|
2003-04-25 21:45:10 +02:00
|
|
|
|
|
|
|
/*
|
2007-09-27 00:36:30 +02:00
|
|
|
* assign_hook and show_hook subroutines
|
2003-04-25 21:45:10 +02:00
|
|
|
*/
|
|
|
|
|
2004-04-05 05:02:11 +02:00
|
|
|
static const char *
|
|
|
|
assign_log_destination(const char *value, bool doit, GucSource source)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
char *rawstring;
|
|
|
|
List *elemlist;
|
|
|
|
ListCell *l;
|
|
|
|
int newlogdest = 0;
|
|
|
|
|
2004-04-05 05:02:11 +02:00
|
|
|
/* Need a modifiable copy of string */
|
|
|
|
rawstring = pstrdup(value);
|
|
|
|
|
|
|
|
/* Parse string into list of identifiers */
|
2004-08-29 07:07:03 +02:00
|
|
|
if (!SplitIdentifierString(rawstring, ',', &elemlist))
|
2004-04-05 05:02:11 +02:00
|
|
|
{
|
|
|
|
/* syntax error in list */
|
|
|
|
pfree(rawstring);
|
2004-05-31 01:40:41 +02:00
|
|
|
list_free(elemlist);
|
2007-12-28 01:23:23 +01:00
|
|
|
ereport(GUC_complaint_elevel(source),
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2005-10-15 04:49:52 +02:00
|
|
|
errmsg("invalid list syntax for parameter \"log_destination\"")));
|
2004-04-05 05:02:11 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach(l, elemlist)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
char *tok = (char *) lfirst(l);
|
|
|
|
|
|
|
|
if (pg_strcasecmp(tok, "stderr") == 0)
|
2004-04-05 05:02:11 +02:00
|
|
|
newlogdest |= LOG_DESTINATION_STDERR;
|
2007-08-19 03:41:25 +02:00
|
|
|
else if (pg_strcasecmp(tok, "csvlog") == 0)
|
2007-11-15 22:14:46 +01:00
|
|
|
newlogdest |= LOG_DESTINATION_CSVLOG;
|
2004-04-05 05:02:11 +02:00
|
|
|
#ifdef HAVE_SYSLOG
|
2004-08-29 07:07:03 +02:00
|
|
|
else if (pg_strcasecmp(tok, "syslog") == 0)
|
2004-04-05 05:02:11 +02:00
|
|
|
newlogdest |= LOG_DESTINATION_SYSLOG;
|
|
|
|
#endif
|
|
|
|
#ifdef WIN32
|
2004-08-29 07:07:03 +02:00
|
|
|
else if (pg_strcasecmp(tok, "eventlog") == 0)
|
2004-04-05 05:02:11 +02:00
|
|
|
newlogdest |= LOG_DESTINATION_EVENTLOG;
|
|
|
|
#endif
|
2004-08-29 07:07:03 +02:00
|
|
|
else
|
|
|
|
{
|
2007-12-28 01:23:23 +01:00
|
|
|
ereport(GUC_complaint_elevel(source),
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2005-10-15 04:49:52 +02:00
|
|
|
errmsg("unrecognized \"log_destination\" key word: \"%s\"",
|
|
|
|
tok)));
|
2004-04-05 05:02:11 +02:00
|
|
|
pfree(rawstring);
|
2004-05-31 01:40:41 +02:00
|
|
|
list_free(elemlist);
|
2004-04-05 05:02:11 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-24 21:51:23 +02:00
|
|
|
if (doit)
|
|
|
|
Log_destination = newlogdest;
|
|
|
|
|
2004-04-05 05:02:11 +02:00
|
|
|
pfree(rawstring);
|
2004-05-31 01:40:41 +02:00
|
|
|
list_free(elemlist);
|
2004-04-05 05:02:11 +02:00
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2003-04-25 21:45:10 +02:00
|
|
|
#ifdef HAVE_SYSLOG
|
|
|
|
|
|
|
|
static const char *
|
2005-10-14 22:53:56 +02:00
|
|
|
assign_syslog_facility(const char *facility, bool doit, GucSource source)
|
2003-04-25 21:45:10 +02:00
|
|
|
{
|
2005-10-15 04:49:52 +02:00
|
|
|
int syslog_fac;
|
2005-10-14 22:53:56 +02:00
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
if (pg_strcasecmp(facility, "LOCAL0") == 0)
|
2005-10-14 22:53:56 +02:00
|
|
|
syslog_fac = LOG_LOCAL0;
|
|
|
|
else if (pg_strcasecmp(facility, "LOCAL1") == 0)
|
|
|
|
syslog_fac = LOG_LOCAL1;
|
|
|
|
else if (pg_strcasecmp(facility, "LOCAL2") == 0)
|
|
|
|
syslog_fac = LOG_LOCAL2;
|
|
|
|
else if (pg_strcasecmp(facility, "LOCAL3") == 0)
|
|
|
|
syslog_fac = LOG_LOCAL3;
|
|
|
|
else if (pg_strcasecmp(facility, "LOCAL4") == 0)
|
|
|
|
syslog_fac = LOG_LOCAL4;
|
|
|
|
else if (pg_strcasecmp(facility, "LOCAL5") == 0)
|
|
|
|
syslog_fac = LOG_LOCAL5;
|
|
|
|
else if (pg_strcasecmp(facility, "LOCAL6") == 0)
|
|
|
|
syslog_fac = LOG_LOCAL6;
|
|
|
|
else if (pg_strcasecmp(facility, "LOCAL7") == 0)
|
|
|
|
syslog_fac = LOG_LOCAL7;
|
|
|
|
else
|
|
|
|
return NULL; /* reject */
|
|
|
|
|
|
|
|
if (doit)
|
|
|
|
{
|
|
|
|
syslog_facility = syslog_fac;
|
|
|
|
set_syslog_parameters(syslog_ident_str ? syslog_ident_str : "postgres",
|
|
|
|
syslog_facility);
|
|
|
|
}
|
|
|
|
|
|
|
|
return facility;
|
2003-04-25 21:45:10 +02:00
|
|
|
}
|
2005-10-14 22:53:56 +02:00
|
|
|
|
|
|
|
static const char *
|
|
|
|
assign_syslog_ident(const char *ident, bool doit, GucSource source)
|
|
|
|
{
|
|
|
|
if (doit)
|
|
|
|
set_syslog_parameters(ident, syslog_facility);
|
|
|
|
|
|
|
|
return ident;
|
|
|
|
}
|
2005-10-15 04:49:52 +02:00
|
|
|
#endif /* HAVE_SYSLOG */
|
2003-04-25 21:45:10 +02:00
|
|
|
|
|
|
|
|
|
|
|
static const char *
|
2004-01-19 20:04:40 +01:00
|
|
|
assign_defaultxactisolevel(const char *newval, bool doit, GucSource source)
|
2003-04-25 21:45:10 +02:00
|
|
|
{
|
2004-05-07 02:24:59 +02:00
|
|
|
if (pg_strcasecmp(newval, "serializable") == 0)
|
2003-04-25 21:45:10 +02:00
|
|
|
{
|
|
|
|
if (doit)
|
|
|
|
DefaultXactIsoLevel = XACT_SERIALIZABLE;
|
|
|
|
}
|
2004-05-07 02:24:59 +02:00
|
|
|
else if (pg_strcasecmp(newval, "repeatable read") == 0)
|
2003-11-06 23:08:15 +01:00
|
|
|
{
|
|
|
|
if (doit)
|
|
|
|
DefaultXactIsoLevel = XACT_REPEATABLE_READ;
|
|
|
|
}
|
2004-05-07 02:24:59 +02:00
|
|
|
else if (pg_strcasecmp(newval, "read committed") == 0)
|
2003-04-25 21:45:10 +02:00
|
|
|
{
|
|
|
|
if (doit)
|
|
|
|
DefaultXactIsoLevel = XACT_READ_COMMITTED;
|
|
|
|
}
|
2004-05-07 02:24:59 +02:00
|
|
|
else if (pg_strcasecmp(newval, "read uncommitted") == 0)
|
2003-11-06 23:08:15 +01:00
|
|
|
{
|
|
|
|
if (doit)
|
|
|
|
DefaultXactIsoLevel = XACT_READ_UNCOMMITTED;
|
|
|
|
}
|
2003-04-25 21:45:10 +02:00
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
return newval;
|
|
|
|
}
|
|
|
|
|
2007-03-20 00:38:32 +01:00
|
|
|
static const char *
|
|
|
|
assign_session_replication_role(const char *newval, bool doit, GucSource source)
|
|
|
|
{
|
2007-11-15 22:14:46 +01:00
|
|
|
int newrole;
|
2007-06-05 23:50:19 +02:00
|
|
|
|
2007-03-20 00:38:32 +01:00
|
|
|
if (pg_strcasecmp(newval, "origin") == 0)
|
2007-06-05 23:50:19 +02:00
|
|
|
newrole = SESSION_REPLICATION_ROLE_ORIGIN;
|
2007-03-20 00:38:32 +01:00
|
|
|
else if (pg_strcasecmp(newval, "replica") == 0)
|
2007-06-05 23:50:19 +02:00
|
|
|
newrole = SESSION_REPLICATION_ROLE_REPLICA;
|
2007-03-20 00:38:32 +01:00
|
|
|
else if (pg_strcasecmp(newval, "local") == 0)
|
2007-06-05 23:50:19 +02:00
|
|
|
newrole = SESSION_REPLICATION_ROLE_LOCAL;
|
2007-03-20 00:38:32 +01:00
|
|
|
else
|
|
|
|
return NULL;
|
2007-06-05 23:50:19 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Must flush the plan cache when changing replication role; but don't
|
|
|
|
* flush unnecessarily.
|
|
|
|
*/
|
|
|
|
if (doit && SessionReplicationRole != newrole)
|
|
|
|
{
|
|
|
|
ResetPlanCache();
|
|
|
|
SessionReplicationRole = newrole;
|
|
|
|
}
|
|
|
|
|
2007-03-20 00:38:32 +01:00
|
|
|
return newval;
|
|
|
|
}
|
|
|
|
|
2005-03-20 00:27:11 +01:00
|
|
|
static const char *
|
|
|
|
show_num_temp_buffers(void)
|
|
|
|
{
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* We show the GUC var until local buffers have been initialized, and
|
|
|
|
* NLocBuffer afterwards.
|
2005-03-20 00:27:11 +01:00
|
|
|
*/
|
|
|
|
static char nbuf[32];
|
|
|
|
|
|
|
|
sprintf(nbuf, "%d", NLocBuffer ? NLocBuffer : num_temp_buffers);
|
|
|
|
return nbuf;
|
|
|
|
}
|
|
|
|
|
2003-05-14 05:26:03 +02:00
|
|
|
static bool
|
2004-01-19 20:04:40 +01:00
|
|
|
assign_phony_autocommit(bool newval, bool doit, GucSource source)
|
2003-05-14 05:26:03 +02:00
|
|
|
{
|
|
|
|
if (!newval)
|
|
|
|
{
|
2007-12-28 01:23:23 +01:00
|
|
|
ereport(GUC_complaint_elevel(source),
|
|
|
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
|
|
errmsg("SET AUTOCOMMIT TO OFF is no longer supported")));
|
2003-05-14 05:26:03 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
static const char *
|
|
|
|
assign_custom_variable_classes(const char *newval, bool doit, GucSource source)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
/*
|
|
|
|
* Check syntax. newval must be a comma separated list of identifiers.
|
2007-09-10 02:57:22 +02:00
|
|
|
* Whitespace is allowed but removed from the result.
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
*/
|
2004-08-29 07:07:03 +02:00
|
|
|
bool hasSpaceAfterToken = false;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
const char *cp = newval;
|
2004-08-29 07:07:03 +02:00
|
|
|
int symLen = 0;
|
2007-09-10 02:57:22 +02:00
|
|
|
char c;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
StringInfoData buf;
|
|
|
|
|
|
|
|
initStringInfo(&buf);
|
2007-09-10 02:57:22 +02:00
|
|
|
while ((c = *cp++) != '\0')
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2006-09-22 23:39:58 +02:00
|
|
|
if (isspace((unsigned char) c))
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
if (symLen > 0)
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
hasSpaceAfterToken = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
if (c == ',')
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2007-09-10 02:57:22 +02:00
|
|
|
if (symLen > 0) /* terminate identifier */
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
|
|
|
appendStringInfoChar(&buf, ',');
|
2007-09-10 02:57:22 +02:00
|
|
|
symLen = 0;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
}
|
2007-09-10 02:57:22 +02:00
|
|
|
hasSpaceAfterToken = false;
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2006-09-22 23:39:58 +02:00
|
|
|
if (hasSpaceAfterToken || !isalnum((unsigned char) c))
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Syntax error due to token following space after token or non
|
|
|
|
* alpha numeric character
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
*/
|
2004-08-31 21:28:51 +02:00
|
|
|
pfree(buf.data);
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2007-09-10 02:57:22 +02:00
|
|
|
appendStringInfoChar(&buf, c);
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
symLen++;
|
|
|
|
}
|
|
|
|
|
2004-08-31 21:28:51 +02:00
|
|
|
/* Remove stray ',' at end */
|
2004-08-29 07:07:03 +02:00
|
|
|
if (symLen == 0 && buf.len > 0)
|
2004-08-31 21:28:51 +02:00
|
|
|
buf.data[--buf.len] = '\0';
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
/* GUC wants the result malloc'd */
|
|
|
|
newval = guc_strdup(LOG, buf.data);
|
The patch adresses the TODO list item "Allow external interfaces to
extend the GUC variable set".
Plugin modules like the pl<lang> modules needs a way to declare
configuration parameters. The postmaster has no knowledge of such
modules when it reads the postgresql.conf file. Rather than allowing
totally unknown configuration parameters, the concept of a variable
"class" is introduced. Variables that belongs to a declared classes will
create a placeholder value of string type and will not generate an
error. When a module is loaded, it will declare variables for such a
class and make those variables "consume" any placeholders that has been
defined. Finally, the module will generate warnings for unrecognized
placeholders defined for its class.
More detail:
The design is outlined after the suggestions made by Tom Lane and Joe
Conway in this thread:
http://archives.postgresql.org/pgsql-hackers/2004-02/msg00229.php
A new string variable 'custom_variable_classes' is introduced. This
variable is a comma separated string of identifiers. Each identifier
denots a 'class' that will allow its members to be added without error.
This variable must be defined in postmaster.conf.
The lexer (guc_file.l) is changed so that it can accept a qualified name
in the form <ID>.<ID> as the name of a variable. I also changed so that
the 'custom_variable_classes', if found, is added first of all variables
in order to remove the order of declaration issue.
The guc_variables table is made more dynamic. It is originally created
with 20% slack and can grow dynamically. A capacity is introduced to
avoid resizing every time a new variable is added. guc_variables and
num_guc_variables becomes static (hidden).
The GucInfoMain now uses the new function get_guc_variables() and
GetNumConfigOptions instead or using the guc_variables directly.
The find_option() function, when passed a missing name, will check if
the name is qualified. If the name is qualified and if the qualifier
denotes a class included in the 'custom_variable_classes', a placeholder
variable will be created. Such a placeholder will not participate in a
list operation but will otherwise function as a normal string variable.
Define<type>GucVariable() functions will be added, one for each variable
type. They are inteded to be used by add-on modules like the pl<lang>
mappings. Example:
extern void DefineCustomBoolVariable(
const char* name,
const char* short_desc,
const char* long_desc,
bool* valueAddr,
GucContext context,
GucBoolAssignHook assign_hook,
GucShowHook show_hook);
(I created typedefs for the assign-hook and show-hook functions). A call
to these functions will define a new GUC-variable. If a placeholder
exists it will be replaced but it's value will be used in place of the
default value. The valueAddr is assumed ot point at a default value when
the define function is called. The only constraint that is imposed on a
Custom variable is that its name is qualified.
Finally, a function:
void EmittWarningsOnPlacholders(const char* className)
was added. This function should be called when a module has completed
its variable definitions. At that time, no placeholders should remain
for the class that the module uses. If they do, elog(INFO, ...) messages
will be issued to inform the user that unrecognized variables are
present.
Thomas Hallgren
2004-05-26 17:07:41 +02:00
|
|
|
|
|
|
|
pfree(buf.data);
|
|
|
|
return newval;
|
|
|
|
}
|
2003-04-25 21:45:10 +02:00
|
|
|
|
2006-01-05 11:07:46 +01:00
|
|
|
static bool
|
|
|
|
assign_debug_assertions(bool newval, bool doit, GucSource source)
|
|
|
|
{
|
|
|
|
#ifndef USE_ASSERT_CHECKING
|
|
|
|
if (newval)
|
2007-12-28 01:23:23 +01:00
|
|
|
{
|
|
|
|
ereport(GUC_complaint_elevel(source),
|
2006-01-05 11:07:46 +01:00
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
2006-10-04 02:30:14 +02:00
|
|
|
errmsg("assertion checking is not supported by this build")));
|
2007-12-28 01:23:23 +01:00
|
|
|
return false;
|
|
|
|
}
|
2006-01-05 11:07:46 +01:00
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2005-12-30 01:13:50 +01:00
|
|
|
static bool
|
|
|
|
assign_ssl(bool newval, bool doit, GucSource source)
|
|
|
|
{
|
|
|
|
#ifndef USE_SSL
|
|
|
|
if (newval)
|
2007-12-28 01:23:23 +01:00
|
|
|
{
|
|
|
|
ereport(GUC_complaint_elevel(source),
|
2005-12-30 01:13:50 +01:00
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("SSL is not supported by this build")));
|
2007-12-28 01:23:23 +01:00
|
|
|
return false;
|
|
|
|
}
|
2005-12-30 01:13:50 +01:00
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2004-05-07 03:34:08 +02:00
|
|
|
static bool
|
|
|
|
assign_stage_log_stats(bool newval, bool doit, GucSource source)
|
|
|
|
{
|
2004-08-31 21:28:51 +02:00
|
|
|
if (newval && log_statement_stats)
|
2004-05-07 03:34:08 +02:00
|
|
|
{
|
2007-12-28 01:23:23 +01:00
|
|
|
ereport(GUC_complaint_elevel(source),
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("cannot enable parameter when \"log_statement_stats\" is true")));
|
2004-09-24 21:43:03 +02:00
|
|
|
/* source == PGC_S_OVERRIDE means do it anyway, eg at xact abort */
|
2007-12-28 01:23:23 +01:00
|
|
|
if (source != PGC_S_OVERRIDE)
|
2004-08-31 21:28:51 +02:00
|
|
|
return false;
|
2004-05-07 03:34:08 +02:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
assign_log_stats(bool newval, bool doit, GucSource source)
|
|
|
|
{
|
2004-08-31 21:28:51 +02:00
|
|
|
if (newval &&
|
|
|
|
(log_parser_stats || log_planner_stats || log_executor_stats))
|
2004-05-07 03:34:08 +02:00
|
|
|
{
|
2007-12-28 01:23:23 +01:00
|
|
|
ereport(GUC_complaint_elevel(source),
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("cannot enable \"log_statement_stats\" when "
|
|
|
|
"\"log_parser_stats\", \"log_planner_stats\", "
|
|
|
|
"or \"log_executor_stats\" is true")));
|
2004-09-24 21:43:03 +02:00
|
|
|
/* source == PGC_S_OVERRIDE means do it anyway, eg at xact abort */
|
2007-12-28 01:23:23 +01:00
|
|
|
if (source != PGC_S_OVERRIDE)
|
2004-08-31 21:28:51 +02:00
|
|
|
return false;
|
2004-05-07 03:34:08 +02:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
static bool
|
|
|
|
assign_transaction_read_only(bool newval, bool doit, GucSource source)
|
|
|
|
{
|
2004-07-28 16:23:31 +02:00
|
|
|
/* Can't go to r/w mode inside a r/o transaction */
|
|
|
|
if (newval == false && XactReadOnly && IsSubTransaction())
|
|
|
|
{
|
2007-12-28 01:23:23 +01:00
|
|
|
ereport(GUC_complaint_elevel(source),
|
|
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
|
errmsg("cannot set transaction read-write mode inside a read-only transaction")));
|
2004-09-24 21:43:03 +02:00
|
|
|
/* source == PGC_S_OVERRIDE means do it anyway, eg at xact abort */
|
2007-12-28 01:23:23 +01:00
|
|
|
if (source != PGC_S_OVERRIDE)
|
2004-09-24 21:43:03 +02:00
|
|
|
return false;
|
2004-07-28 16:23:31 +02:00
|
|
|
}
|
2004-07-01 02:52:04 +02:00
|
|
|
return true;
|
|
|
|
}
|
2004-05-07 03:34:08 +02:00
|
|
|
|
2004-07-11 23:34:04 +02:00
|
|
|
static const char *
|
|
|
|
assign_canonical_path(const char *newval, bool doit, GucSource source)
|
|
|
|
{
|
|
|
|
if (doit)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
char *canon_val = guc_strdup(ERROR, newval);
|
|
|
|
|
2004-07-11 23:34:04 +02:00
|
|
|
canonicalize_path(canon_val);
|
|
|
|
return canon_val;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return newval;
|
|
|
|
}
|
|
|
|
|
2006-05-21 22:10:42 +02:00
|
|
|
static const char *
|
|
|
|
assign_backslash_quote(const char *newval, bool doit, GucSource source)
|
|
|
|
{
|
|
|
|
BackslashQuoteType bq;
|
2006-10-04 02:30:14 +02:00
|
|
|
bool bqbool;
|
2006-05-21 22:10:42 +02:00
|
|
|
|
|
|
|
/*
|
2006-10-04 02:30:14 +02:00
|
|
|
* Although only "on", "off", and "safe_encoding" are documented, we use
|
|
|
|
* parse_bool so we can accept all the likely variants of "on" and "off".
|
2006-05-21 22:10:42 +02:00
|
|
|
*/
|
|
|
|
if (pg_strcasecmp(newval, "safe_encoding") == 0)
|
|
|
|
bq = BACKSLASH_QUOTE_SAFE_ENCODING;
|
|
|
|
else if (parse_bool(newval, &bqbool))
|
|
|
|
{
|
|
|
|
bq = bqbool ? BACKSLASH_QUOTE_ON : BACKSLASH_QUOTE_OFF;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return NULL; /* reject */
|
|
|
|
|
|
|
|
if (doit)
|
|
|
|
backslash_quote = bq;
|
|
|
|
|
|
|
|
return newval;
|
|
|
|
}
|
|
|
|
|
2006-07-25 05:51:23 +02:00
|
|
|
static const char *
|
|
|
|
assign_timezone_abbreviations(const char *newval, bool doit, GucSource source)
|
|
|
|
{
|
2006-07-29 05:02:56 +02:00
|
|
|
/*
|
|
|
|
* The powerup value shown above for timezone_abbreviations is "UNKNOWN".
|
|
|
|
* When we see this we just do nothing. If this value isn't overridden
|
|
|
|
* from the config file then pg_timezone_abbrev_initialize() will
|
2006-10-04 02:30:14 +02:00
|
|
|
* eventually replace it with "Default". This hack has two purposes: to
|
|
|
|
* avoid wasting cycles loading values that might soon be overridden from
|
|
|
|
* the config file, and to avoid trying to read the timezone abbrev files
|
|
|
|
* during InitializeGUCOptions(). The latter doesn't work in an
|
|
|
|
* EXEC_BACKEND subprocess because my_exec_path hasn't been set yet and so
|
|
|
|
* we can't locate PGSHAREDIR. (Essentially the same hack is used to
|
|
|
|
* delay initializing TimeZone ... if we have any more, we should try to
|
|
|
|
* clean up and centralize this mechanism ...)
|
2006-07-29 05:02:56 +02:00
|
|
|
*/
|
|
|
|
if (strcmp(newval, "UNKNOWN") == 0)
|
|
|
|
{
|
|
|
|
return newval;
|
|
|
|
}
|
|
|
|
|
2006-07-25 05:51:23 +02:00
|
|
|
/* Loading abbrev file is expensive, so only do it when value changes */
|
2006-07-29 05:02:56 +02:00
|
|
|
if (timezone_abbreviations_string == NULL ||
|
|
|
|
strcmp(timezone_abbreviations_string, newval) != 0)
|
2006-07-25 05:51:23 +02:00
|
|
|
{
|
2006-10-04 02:30:14 +02:00
|
|
|
int elevel;
|
2006-07-25 05:51:23 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If reading config file, only the postmaster should bleat loudly
|
2006-10-04 02:30:14 +02:00
|
|
|
* about problems. Otherwise, it's just this one process doing it,
|
2006-07-25 05:51:23 +02:00
|
|
|
* and we use WARNING message level.
|
|
|
|
*/
|
|
|
|
if (source == PGC_S_FILE)
|
2007-12-28 01:23:23 +01:00
|
|
|
elevel = IsUnderPostmaster ? DEBUG3 : LOG;
|
2006-07-25 05:51:23 +02:00
|
|
|
else
|
|
|
|
elevel = WARNING;
|
|
|
|
if (!load_tzoffsets(newval, doit, elevel))
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return newval;
|
|
|
|
}
|
|
|
|
|
2006-07-29 05:02:56 +02:00
|
|
|
/*
|
|
|
|
* pg_timezone_abbrev_initialize --- set default value if not done already
|
|
|
|
*
|
|
|
|
* This is called after initial loading of postgresql.conf. If no
|
|
|
|
* timezone_abbreviations setting was found therein, select default.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
pg_timezone_abbrev_initialize(void)
|
|
|
|
{
|
|
|
|
if (strcmp(timezone_abbreviations_string, "UNKNOWN") == 0)
|
|
|
|
{
|
|
|
|
SetConfigOption("timezone_abbreviations", "Default",
|
|
|
|
PGC_POSTMASTER, PGC_S_ARGV);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-01-19 17:58:46 +01:00
|
|
|
static const char *
|
|
|
|
assign_xmlbinary(const char *newval, bool doit, GucSource source)
|
|
|
|
{
|
|
|
|
XmlBinaryType xb;
|
|
|
|
|
|
|
|
if (pg_strcasecmp(newval, "base64") == 0)
|
|
|
|
xb = XMLBINARY_BASE64;
|
|
|
|
else if (pg_strcasecmp(newval, "hex") == 0)
|
|
|
|
xb = XMLBINARY_HEX;
|
|
|
|
else
|
|
|
|
return NULL; /* reject */
|
|
|
|
|
|
|
|
if (doit)
|
|
|
|
xmlbinary = xb;
|
|
|
|
|
|
|
|
return newval;
|
|
|
|
}
|
|
|
|
|
2007-01-25 12:53:52 +01:00
|
|
|
static const char *
|
|
|
|
assign_xmloption(const char *newval, bool doit, GucSource source)
|
|
|
|
{
|
|
|
|
XmlOptionType xo;
|
|
|
|
|
|
|
|
if (pg_strcasecmp(newval, "document") == 0)
|
|
|
|
xo = XMLOPTION_DOCUMENT;
|
|
|
|
else if (pg_strcasecmp(newval, "content") == 0)
|
|
|
|
xo = XMLOPTION_CONTENT;
|
|
|
|
else
|
|
|
|
return NULL; /* reject */
|
|
|
|
|
|
|
|
if (doit)
|
|
|
|
xmloption = xo;
|
|
|
|
|
|
|
|
return newval;
|
|
|
|
}
|
|
|
|
|
2007-09-27 00:36:30 +02:00
|
|
|
static const char *
|
|
|
|
show_archive_command(void)
|
|
|
|
{
|
|
|
|
if (XLogArchiveMode)
|
|
|
|
return XLogArchiveCommand;
|
|
|
|
else
|
|
|
|
return "(disabled)";
|
|
|
|
}
|
|
|
|
|
2005-07-30 17:17:26 +02:00
|
|
|
static bool
|
|
|
|
assign_tcp_keepalives_idle(int newval, bool doit, GucSource source)
|
|
|
|
{
|
2005-09-12 04:26:33 +02:00
|
|
|
if (doit)
|
2005-07-30 17:17:26 +02:00
|
|
|
return (pq_setkeepalivesidle(newval, MyProcPort) == STATUS_OK);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
show_tcp_keepalives_idle(void)
|
|
|
|
{
|
2005-09-12 04:26:33 +02:00
|
|
|
static char nbuf[16];
|
|
|
|
|
|
|
|
snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesidle(MyProcPort));
|
2005-07-30 17:17:26 +02:00
|
|
|
return nbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
assign_tcp_keepalives_interval(int newval, bool doit, GucSource source)
|
|
|
|
{
|
2005-09-12 04:26:33 +02:00
|
|
|
if (doit)
|
2005-07-30 17:17:26 +02:00
|
|
|
return (pq_setkeepalivesinterval(newval, MyProcPort) == STATUS_OK);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
show_tcp_keepalives_interval(void)
|
|
|
|
{
|
2005-09-12 04:26:33 +02:00
|
|
|
static char nbuf[16];
|
|
|
|
|
|
|
|
snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesinterval(MyProcPort));
|
2005-07-30 17:17:26 +02:00
|
|
|
return nbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
assign_tcp_keepalives_count(int newval, bool doit, GucSource source)
|
|
|
|
{
|
2005-09-12 04:26:33 +02:00
|
|
|
if (doit)
|
2005-07-30 17:17:26 +02:00
|
|
|
return (pq_setkeepalivescount(newval, MyProcPort) == STATUS_OK);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
show_tcp_keepalives_count(void)
|
|
|
|
{
|
2005-09-12 04:26:33 +02:00
|
|
|
static char nbuf[16];
|
|
|
|
|
|
|
|
snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivescount(MyProcPort));
|
2005-07-30 17:17:26 +02:00
|
|
|
return nbuf;
|
|
|
|
}
|
2004-10-10 01:13:22 +02:00
|
|
|
|
2007-04-16 20:30:04 +02:00
|
|
|
static bool
|
|
|
|
assign_maxconnections(int newval, bool doit, GucSource source)
|
|
|
|
{
|
2007-08-08 18:00:46 +02:00
|
|
|
if (newval + autovacuum_max_workers > INT_MAX / 4)
|
|
|
|
return false;
|
2007-04-16 20:30:04 +02:00
|
|
|
|
2007-08-08 18:00:46 +02:00
|
|
|
if (doit)
|
2007-04-16 20:30:04 +02:00
|
|
|
MaxBackends = newval + autovacuum_max_workers;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
assign_autovacuum_max_workers(int newval, bool doit, GucSource source)
|
|
|
|
{
|
2007-08-08 18:00:46 +02:00
|
|
|
if (newval + MaxConnections > INT_MAX / 4)
|
|
|
|
return false;
|
2007-04-16 20:30:04 +02:00
|
|
|
|
2007-08-08 18:00:46 +02:00
|
|
|
if (doit)
|
2007-04-16 20:30:04 +02:00
|
|
|
MaxBackends = newval + MaxConnections;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2005-09-12 04:26:33 +02:00
|
|
|
|
2002-11-01 23:52:34 +01:00
|
|
|
#include "guc-file.c"
|